#!/bin/sh

# Copyright (c) 2021-2024 刘富频
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# last line mode :set foldmethod=marker
# command mode zM  fold close all
# command mode zR  fold open all

# {{{ coding convention

# 1. The variable/function name starts with underscore "_" means that it is a private variable/function.
# 2. 0 represents the boolean value false
# 3. 1 represents the boolean value true

# }}}
##############################################################################
# {{{ utils

COLOR_RED='\033[0;31m'          # Red
COLOR_GREEN='\033[0;32m'        # Green
COLOR_YELLOW='\033[0;33m'       # Yellow
COLOR_BLUE='\033[0;94m'         # Blue
COLOR_PURPLE='\033[0;35m'       # Purple
COLOR_OFF='\033[0m'             # Reset

print() {
    printf '%b' "$*"
}

echo() {
    printf '%b\n' "$*"
}

note() {
    printf '%b\n' "${COLOR_YELLOW}🔔  $*${COLOR_OFF}" >&2
}

warn() {
    printf '%b\n' "${COLOR_YELLOW}🔥  $*${COLOR_OFF}" >&2
}

success() {
    printf '%b\n' "${COLOR_GREEN}[✔] $*${COLOR_OFF}" >&2
}

error() {
    printf '%b\n' "${COLOR_RED}💔  $*${COLOR_OFF}" >&2
}

abort() {
    EXIT_STATUS_CODE="$1"
    shift
    printf '%b\n' "${COLOR_RED}💔  $*${COLOR_OFF}" >&2
    exit "$EXIT_STATUS_CODE"
}

step() {
    STEP_NUM=$((${STEP_NUM-0} + 1))
    STEP_MESSAGE="$*"
    printf '\n%b\n' "${COLOR_PURPLE}=>> STEP ${STEP_NUM} : ${STEP_MESSAGE} ${COLOR_OFF}"
}

run() {
    echo "${COLOR_PURPLE}==>${COLOR_OFF} ${COLOR_GREEN}$@${COLOR_OFF}"
    eval "$@"
}

list_size() {
    printf '%s\n' "$#"
}

isInteger() {
    case "${1#[+-]}" in
        (*[!0123456789]*) return 1 ;;
        ('')              return 1 ;;
        (*)               return 0 ;;
    esac
}

isCrossBuild() {
    [ "$CROSS_COMPILING" = 1 ]
}

bppend_to_PATH() {
    case ":${PATH}:" in
        *:"$1":*) ;;
        *) export PATH="$1:$PATH" ;;
    esac
}

bppend_to_ACLOCAL_PATH() {
    case ":${ACLOCAL_PATH}:" in
        *:"$1":*) ;;
        *) export ACLOCAL_PATH="$1:$ACLOCAL_PATH" ;;
    esac
}

git() {
    if [ -n "$SSL_CERT_FILE" ] ; then
        command git -c http.sslCAInfo="$SSL_CERT_FILE" "$@"
    else
        command git "$@"
    fi
}

# git_checkout <URL> --ref-from=<FROM> --ref-to=<TO> --depth=<N> -B <CHECKOUT-BRANCH-NAME> -C <WORKDIR> --recursive
git_checkout() {
    GIT_CHECKOUT_OLDCWD="$PWD"

    unset GIT_FETCH_FROM_URL
    unset GIT_FETCH_FROM_REF
    unset GIT_FETCH_TO___REF
    unset GIT_FETCH_DEPTH
    unset GIT_FETCH_SUBMODULE_RECURSIVE
    unset GIT_CHECKOUT_BRANCH_NAME
    unset GIT_WORK_DIR

    if [ -z "$PPKG_URL_TRANSFORM" ] ; then
        GIT_FETCH_FROM_URL="$1"
    else
        GIT_FETCH_FROM_URL="$("$PPKG_URL_TRANSFORM" "$1")"
    fi

    shift

    while [ -n "$1" ]
    do
        case $1 in
            --ref-from=*)
                GIT_FETCH_FROM_REF="${1#*=}"
                ;;
            --ref-to=*)
                GIT_FETCH_TO___REF="${1#*=}"
                ;;
            --depth=*)
                GIT_FETCH_DEPTH="${1#*=}"
                ;;
            -B) shift
                GIT_CHECKOUT_BRANCH_NAME="${1#*=}"
                ;;
            -C) shift
                GIT_WORK_DIR="$1"
                ;;
            --recursive)
                GIT_FETCH_SUBMODULE_RECURSIVE=1
                ;;
        esac
        shift
    done

    if [ -z "$GIT_FETCH_DEPTH" ] ; then
        GIT_FETCH_DEPTH=1
        GIT_FETCH_OPTION="--depth=1"
    else
        if [ "$GIT_FETCH_DEPTH" = '0' ] ; then
            GIT_FETCH_OPTION=
        else
            GIT_FETCH_OPTION="--depth=$GIT_FETCH_DEPTH"
        fi
    fi

    [ -z "$GIT_FETCH_FROM_REF" ] && GIT_FETCH_FROM_REF='HEAD'
    [ -z "$GIT_FETCH_TO___REF" ] && GIT_FETCH_TO___REF='refs/remotes/origin/master'

    [ -z "$GIT_CHECKOUT_BRANCH_NAME" ] && GIT_CHECKOUT_BRANCH_NAME="${GIT_FETCH_TO___REF##*/}"

    if [    -n "$GIT_WORK_DIR" ] ; then
        [   -d "$GIT_WORK_DIR" ] || run install -d "$GIT_WORK_DIR"
        run cd "$GIT_WORK_DIR"
    fi

    run git -c init.defaultBranch=master init
    run git remote add origin "$GIT_FETCH_FROM_URL"
    run git -c protocol.version=2 fetch --progress $GIT_FETCH_OPTION origin "$GIT_FETCH_FROM_REF:$GIT_FETCH_TO___REF"
    run git checkout --progress --force -B "$GIT_CHECKOUT_BRANCH_NAME" "$GIT_FETCH_TO___REF"

    git_submodule_update_recursive

    run cd "$GIT_CHECKOUT_OLDCWD"
}

git_submodule_update_recursive() {
    if [ -z "$1" ] ; then
        GIT_REPO_ROOT_DIR="$PWD"
    else
        GIT_REPO_ROOT_DIR="$1"
    fi

    GIT_SUBMODULE_HAVE="$(cd "$GIT_REPO_ROOT_DIR" && find . -type f -name '.gitmodules' -print -quit)"

    if [ -n "$GIT_SUBMODULE_HAVE" ] ; then
        if [ -z "$PPKG_URL_TRANSFORM" ] ; then
            run git submodule update --init --recursive
        else
            unset GIT_SUBMODULE_BASEDIR_STACK

            GIT_SUBMODULE_CONFIG_FILE_LIST="$(find "$GIT_REPO_ROOT_DIR" -type f -name '.gitmodules')"

            for f in $GIT_SUBMODULE_CONFIG_FILE_LIST
            do
                if [ -z "$GIT_SUBMODULE_BASEDIR_STACK" ] ; then
                    GIT_SUBMODULE_BASEDIR_STACK="${f%/*}"
                else
                    GIT_SUBMODULE_BASEDIR_STACK="$GIT_SUBMODULE_BASEDIR_STACK;${f%/*}"
                fi
            done

            while [ -n "$GIT_SUBMODULE_BASEDIR_STACK" ]
            do
                case $GIT_SUBMODULE_BASEDIR_STACK in
                    *\;*) GIT_SUBMODULE_BASEDIR="${GIT_SUBMODULE_BASEDIR_STACK##*;}" ; GIT_SUBMODULE_BASEDIR_STACK="${GIT_SUBMODULE_BASEDIR_STACK%;*}" ;;
                    *)    GIT_SUBMODULE_BASEDIR="${GIT_SUBMODULE_BASEDIR_STACK}"     ; GIT_SUBMODULE_BASEDIR_STACK=
                esac

                run cd "$GIT_SUBMODULE_BASEDIR"

                GIT_SUBMODULE_NAME_LIST="$(sed -n '/\[submodule ".*"\]/p' .gitmodules | sed 's|\[submodule "\(.*\)"\]|\1|')"

                for GIT_SUBMODULE_NAME in $GIT_SUBMODULE_NAME_LIST
                do
                    GIT_SUBMODULE_PATH="$(git config --file=.gitmodules --get "submodule.$GIT_SUBMODULE_NAME.path")"
                    GIT_SUBMODULE_URL="$(git config --file=.gitmodules --get "submodule.$GIT_SUBMODULE_NAME.url")"
                    GIT_SUBMODULE_URI="$("$PPKG_URL_TRANSFORM" "$GIT_SUBMODULE_URL")"

                    run git submodule set-url "$GIT_SUBMODULE_PATH" "$GIT_SUBMODULE_URI"
                done

                run git submodule update --init

                GIT_SUBMODULE_PATH_LIST="$(git submodule | sed 's|^ *||' | cut -d ' ' -f2)"

                for GIT_SUBMODULE_PATH in $GIT_SUBMODULE_PATH_LIST
                do
                    GIT_SUBMODULE_CONFIG_FILE_LIST="$(find "$GIT_SUBMODULE_PATH" -type f -name '.gitmodules')"

                    for f in $GIT_SUBMODULE_CONFIG_FILE_LIST
                    do
                        if [ -z "$GIT_SUBMODULE_BASEDIR_STACK" ] ; then
                            GIT_SUBMODULE_BASEDIR_STACK="$GIT_SUBMODULE_BASEDIR/${f%/*}"
                        else
                            GIT_SUBMODULE_BASEDIR_STACK="$GIT_SUBMODULE_BASEDIR_STACK;$GIT_SUBMODULE_BASEDIR/${f%/*}"
                        fi
                    done
                done
            done
        fi
    fi
}

# check if the given two versions match the condition
#
# condition:
# eq  equal
# ne  not equal
# gt  greater than
# lt  less than
# ge  greater than or equal
# le  less than or equal
#
# examples:
# version_match 1.15.3 eq 1.16.0
# version_match 1.15.3 lt 1.16.0
# version_match 1.15.3 gt 1.16.0
# version_match 1.15.3 le 1.16.0
# version_match 1.15.3 ge 1.16.0
version_match() {
    case $2 in
        eq)  [ "$1"  = "$3" ] ;;
        ne)  [ "$1" != "$3" ] ;;
        le)
            if [ "$1" = "$3" ] ; then
                return 0
            fi
            [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | head -n 1)" ]
            ;;
        ge)
            if [ "$1" = "$3" ] ; then
                return 0
            fi
            [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | tail -n 1)" ]
            ;;
        lt)
            if [ "$1" = "$3" ] ; then
                return 1
            fi
            [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | head -n 1)" ]
            ;;
        gt)
            if [ "$1" = "$3" ] ; then
                return 1
            fi
            [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | tail -n 1)" ]
            ;;
        *)  abort 1 "version_compare: $2: not supported operator."
    esac
}

# }}}
##############################################################################
# {{{ wfetch

# wfetch <URL> [--uri=<URL-MIRROR>] [--sha256=<SHA256>] [-o <OUTPUT-PATH>] [-q] [--no-buffer]
#
# If -o <OUTPUT-PATH> option is unspecified, the result will be written to ./$(basename <URL>)
#
# If <OUTPUT-PATH> is -, then the result will be written to stdout.
#
# If <OUTPUT-PATH> is . .. or ends with slash(/), then it will be treated as a directory, otherwise, it will be treated as a filepath.
#
# If <OUTPUT-PATH> is treated as a directory, then it will be expanded to <OUTPUT-PATH>/$(basename <URL>)
#
# influential environment variable:
# PPKG_URL_TRANSFORM
wfetch() {
    unset FETCH_UTS
    unset FETCH_SHA

    unset FETCH_URL
    unset FETCH_URI

    unset FETCH_PATH

    unset FETCH_OUTPUT_DIR
    unset FETCH_OUTPUT_FILEPATH
    unset FETCH_OUTPUT_FILENAME

    unset FETCH_BUFFER_FILEPATH

    unset FETCH_SHA256_EXPECTED

    unset FETCH_SILENT

    unset NOT_BUFFER

    [ -z "$1" ] && abort 1 "wfetch <URL> [OPTION]... , <URL> must be non-empty."

    if [ -z "$PPKG_URL_TRANSFORM" ] ; then
        FETCH_URL="$1"
    else
        FETCH_URL="$("$PPKG_URL_TRANSFORM" "$1")" || return 1
    fi

    shift

    while [ -n "$1" ]
    do
        case $1 in
            --uri=*)
                FETCH_URI="${1#*=}"
                ;;
            --sha256=*)
                FETCH_SHA256_EXPECTED="${1#*=}"
                ;;
            -o) shift
                if [ -z "$1" ] ; then
                    abort 1 "wfetch <URL> -o <PATH> , <PATH> must be non-empty."
                else
                    FETCH_PATH="$1"
                fi
                ;;
            -q)
                FETCH_SILENT=1
                ;;
            --no-buffer)
                NOT_BUFFER=1
                ;;
            *)  abort 1 "wfetch <URL> [--uri=<URL-MIRROR>] [--sha256=<SHA256>] [-o <PATH>] [-q] , unrecognized option: $1"
        esac
        shift
    done

    case $FETCH_PATH in
        -)
            FETCH_BUFFER_FILEPATH='-'
            ;;
        .|'')
            FETCH_OUTPUT_DIR='.'
            FETCH_OUTPUT_FILEPATH="$FETCH_OUTPUT_DIR/${FETCH_URL##*/}"
            ;;
        ..)
            FETCH_OUTPUT_DIR='..'
            FETCH_OUTPUT_FILEPATH="$FETCH_OUTPUT_DIR/${FETCH_URL##*/}"
            ;;
        */)
            FETCH_OUTPUT_DIR="${FETCH_PATH%/}"
            FETCH_OUTPUT_FILEPATH="$FETCH_OUTPUT_DIR/${FETCH_URL##*/}"
            ;;
        *)
            FETCH_OUTPUT_DIR="$(dirname "$FETCH_PATH")"
            FETCH_OUTPUT_FILEPATH="$FETCH_PATH"
    esac

    if [ -n "$FETCH_OUTPUT_FILEPATH" ] ; then
        if [ -f "$FETCH_OUTPUT_FILEPATH" ] ; then
            if [ -n "$FETCH_SHA256_EXPECTED" ] ; then
                if [ "$(sha256sum "$FETCH_OUTPUT_FILEPATH" | cut -d ' ' -f1)" = "$FETCH_SHA256_EXPECTED" ] ; then
                    success "$FETCH_OUTPUT_FILEPATH already have been fetched."
                    return 0
                fi
            fi
        fi

        if [ "$NOT_BUFFER" = 1 ] ; then
            FETCH_BUFFER_FILEPATH="$FETCH_OUTPUT_FILEPATH"
        else
            FETCH_UTS="$(date +%s)"

            FETCH_SHA="$(printf '%s\n' "$FETCH_URL:$$:$FETCH_UTS" | sha256sum | cut -d ' ' -f1)"

            FETCH_BUFFER_FILEPATH="$FETCH_OUTPUT_DIR/$FETCH_SHA.tmp"
        fi
    fi

    for FETCH_TOOL in curl wget http aria2c axel
    do
        if command -v "$FETCH_TOOL" > /dev/null ; then
            break
        else
            unset FETCH_TOOL
        fi
    done

    if [ -z "$FETCH_TOOL" ] ; then
        abort 1 "none of curl wget http aria2c axel command was found, please install one of them then try again."
    fi

    if [                -n "$FETCH_OUTPUT_DIR" ] ; then
        if [ !          -d "$FETCH_OUTPUT_DIR" ] ; then
            run install -d "$FETCH_OUTPUT_DIR" || return 1
        fi
    fi

    case $FETCH_TOOL in
        curl)
            FETCH_ARGS='--fail --retry 20 --retry-delay 30 --location'

            if [ "$FETCH_SILENT" = 1 ] ; then
                FETCH_ARGS="$FETCH_ARGS --no-progress-meter"
            fi

            if [ -n "$PPKG_DNS_SERVERS" ] ; then
                FETCH_ARGS="$FETCH_ARGS --dns-servers $PPKG_DNS_SERVERS"
            fi

            if [ -n "$SSL_CERT_FILE" ] ; then
                FETCH_ARGS="$FETCH_ARGS --cacert $SSL_CERT_FILE"
            fi

            FETCH_ARGS="$FETCH_ARGS -o '$FETCH_BUFFER_FILEPATH'"
            ;;
        wget)
            FETCH_ARGS="--timeout=60 -O '$FETCH_BUFFER_FILEPATH'"
            ;;
        http)
            FETCH_ARGS="--timeout=60 -o '$FETCH_BUFFER_FILEPATH'"
            ;;
        aria2c)
            FETCH_ARGS="-d '$FETCH_OUTPUT_DIR' -o '$FETCH_OUTPUT_FILENAME'"
            ;;
        axel)
            FETCH_ARGS="-o '$FETCH_BUFFER_FILEPATH'"
            ;;
        *)  abort 1 "wfetch() unimplementation: $FETCH_TOOL"
            ;;
    esac

    for i in 1 2 3 4
    do
        case $i in
            1)  URL="$FETCH_URL"
                ;;
            2)  if [ -z "$FETCH_URI" ] ; then
                    if [ -z "$PACKAGE_NAME" ] ; then
                        continue
                    fi

                    URI="${FETCH_URL%%'?'*}"
                    URL="https://distfiles.macports.org/${PACKAGE_NAME%@*}/${URI##*/}"
                else
                    if [ -n "$PPKG_URL_TRANSFORM" ] ; then
                        URL="$("$PPKG_URL_TRANSFORM" "$FETCH_URI")" || return 1
                    else
                        URL="$FETCH_URI"
                    fi
                fi
                ;;
            3)  case $FETCH_URL in
                    https://ftp.gnu.org/gnu/*)
                        URL="$(printf '%s\n' "$FETCH_URL" | sed 's|ftp\.gnu\.org|mirrors.kernel.org|')"
                        ;;
                    *)  continue
                esac
                ;;
            4)  URI="${FETCH_URL%%'?'*}"
                URL="https://fossies.org/linux/misc/${URI##*/}"
                ;;
        esac

        run "$FETCH_TOOL $FETCH_ARGS '$URL'" && break
    done

    [ $? -eq 0 ] || return 1

    if [ -n "$FETCH_OUTPUT_FILEPATH" ] ; then
        if [ -n "$FETCH_SHA256_EXPECTED" ] ; then
            FETCH_SHA256_ACTUAL="$(sha256sum "$FETCH_BUFFER_FILEPATH" | cut -d ' ' -f1)"

            if [ "$FETCH_SHA256_ACTUAL" != "$FETCH_SHA256_EXPECTED" ] ; then
                abort 1 "sha256sum mismatch.\n    expect : $FETCH_SHA256_EXPECTED\n    actual : $FETCH_SHA256_ACTUAL\n"
            fi
        fi

        if [ "$NOT_BUFFER" != 1 ] ; then
            run mv "$FETCH_BUFFER_FILEPATH" "$FETCH_OUTPUT_FILEPATH"
        fi
    fi
}

# __load_formula_repository_config <REPO-NAME> [REPO-PATH]
  __load_formula_repository_config() {
    FORMULA_REPO_NAME="$1"
    FORMULA_REPO_PATH="$PPKG_FORMULA_REPO_ROOT/$1"
    FORMULA_REPO_CONFIG_FILEPATH="$FORMULA_REPO_PATH/.ppkg-formula-repo.yml"

    [ -d "$FORMULA_REPO_PATH" ] || abort 1 "$1 named formula repository does not exist."
    [ -f "$FORMULA_REPO_CONFIG_FILEPATH" ] || abort 1 "$1 formula repository is broken."

    FORMULA_REPO_URL=
    FORMULA_REPO_BRANCH=
    FORMULA_REPO_PINNED=
    FORMULA_REPO_ENABLED=
    FORMULA_REPO_TIMESTAMP_CREATED=
    FORMULA_REPO_TIMESTAMP_UPDATED=

    FORMULA_REPO_URL="$(yq .url "$FORMULA_REPO_CONFIG_FILEPATH")"

    [ "$FORMULA_REPO_URL" = null ] && abort 1 "$1 formula repository is broken."

    FORMULA_REPO_BRANCH="$(yq .branch "$FORMULA_REPO_CONFIG_FILEPATH")"

    [ "$FORMULA_REPO_BRANCH" = null ] && abort 1 "$1 formula repository is broken."

    FORMULA_REPO_PINNED="$(yq .pinned "$FORMULA_REPO_CONFIG_FILEPATH")"

    case $FORMULA_REPO_PINNED in
        0|1) ;;
        *)   abort 1 "$1 formula repository is broken."
    esac

    FORMULA_REPO_ENABLED="$(yq .enabled "$FORMULA_REPO_CONFIG_FILEPATH")"

    case $FORMULA_REPO_ENABLED in
        0|1) ;;
        *)   abort 1 "$1 formula repository is broken."
    esac

    FORMULA_REPO_TIMESTAMP_CREATED="$(yq .created "$FORMULA_REPO_CONFIG_FILEPATH")"

    [ "${#FORMULA_REPO_TIMESTAMP_CREATED}" -eq 10 ] || abort 1 "$1 formula repository is broken."

    FORMULA_REPO_TIMESTAMP_UPDATED="$(yq .updated "$FORMULA_REPO_CONFIG_FILEPATH")"

    if [ "$FORMULA_REPO_TIMESTAMP_UPDATED" = null ] ; then
           FORMULA_REPO_TIMESTAMP_UPDATED=
    else
        [ "${#FORMULA_REPO_TIMESTAMP_UPDATED}" -eq 10 ] || abort 1 "$1 formula repository is broken."
    fi
}

# }}}
##############################################################################
# {{{ ppkg formula-repo-add

# __create_a_formula_repository_then_sync_it <REPO-NAME> <REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable]
  __create_a_formula_repository_then_sync_it() {
    [ -z "$1" ] && abort 1 "please specify a repository name."
    [ -z "$2" ] && abort 1 "please specify a repository url."

    FORMULA_REPO_NAME="$1"
    FORMULA_REPO_URL="$2"

    if [ -z "$PPKG_URL_TRANSFORM" ] ; then
        GIT_FETCH_URL="$FORMULA_REPO_URL"
    else
        GIT_FETCH_URL="$("$PPKG_URL_TRANSFORM" "$FORMULA_REPO_URL")"
    fi

    shift 2

    FORMULA_REPO_BRANCH=
    FORMULA_REPO_PINNED=
    FORMULA_REPO_ENABLED=

    while [ -n "$1" ]
    do
        case $1 in
            --branch=*)
                FORMULA_REPO_BRANCH="${1#*=}"
                ;;
            --pin)
                FORMULA_REPO_PINNED=1
                ;;
            --unpin)
                FORMULA_REPO_PINNED=0
                ;;
            --enable)
                FORMULA_REPO_ENABLED=1
                ;;
            --disable)
                FORMULA_REPO_ENABLED=0
                ;;
            *)  abort 1 "unrecognized argument: $1"
        esac
        shift
    done

    FORMULA_REPO_BRANCH="${FORMULA_REPO_BRANCH:-master}"
    FORMULA_REPO_PINNED="${FORMULA_REPO_PINNED:-0}"
    FORMULA_REPO_ENABLED="${FORMULA_REPO_ENABLED:-1}"

    FORMULA_REPO_PATH="$PPKG_FORMULA_REPO_ROOT/$FORMULA_REPO_NAME"

    if [ -d "$FORMULA_REPO_PATH" ] ; then
        abort 1 "$FORMULA_REPO_NAME named formula repository already exists."
    fi

    printf '%b\n' "${COLOR_PURPLE}==> Adding formula repository${COLOR_OFF} ${COLOR_GREEN}$FORMULA_REPO_NAME${COLOR_OFF}"

    SESSION_DIR="$PPKG_HOME/run/$$/$FORMULA_REPO_NAME"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    run git -c init.defaultBranch=master init
    run git remote add origin "$GIT_FETCH_URL"
    run git -c protocol.version=2 fetch --progress origin "+refs/heads/$FORMULA_REPO_BRANCH:refs/remotes/origin/$FORMULA_REPO_BRANCH"
    run git checkout --progress --force -B "$FORMULA_REPO_BRANCH" "refs/remotes/origin/$FORMULA_REPO_BRANCH"

    cat > .ppkg-formula-repo.yml <<EOF
url: $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $TIMESTAMP_UNIX
EOF

    run install -d        "$PPKG_FORMULA_REPO_ROOT"
    run mv "$SESSION_DIR" "$PPKG_FORMULA_REPO_ROOT/"
}

# }}}
##############################################################################
# {{{ ppkg formula-repo-init

# __create_a_formula_repository <REPO-NAME> <REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable]
  __create_a_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."
    [ -z "$2" ] && abort 1 "please specify a repository url."

    FORMULA_REPO_NAME="$1"

    if [ -z "$PPKG_URL_TRANSFORM" ] ; then
        FORMULA_REPO_URL="$2"
    else
        FORMULA_REPO_URL="$("$PPKG_URL_TRANSFORM" "$2")"
    fi

    shift 2

    FORMULA_REPO_BRANCH=
    FORMULA_REPO_PINNED=
    FORMULA_REPO_ENABLED=

    while [ -n "$1" ]
    do
        case $1 in
            --branch=*)
                FORMULA_REPO_BRANCH="${1#*=}"
                ;;
            --pin)
                FORMULA_REPO_PINNED=1
                ;;
            --unpin)
                FORMULA_REPO_PINNED=0
                ;;
            --enable)
                FORMULA_REPO_ENABLED=1
                ;;
            --disable)
                FORMULA_REPO_ENABLED=0
                ;;
            *)  abort 1 "unrecognized argument: $1"
        esac
        shift
    done

    FORMULA_REPO_BRANCH="${FORMULA_REPO_BRANCH:-master}"
    FORMULA_REPO_PINNED="${FORMULA_REPO_PINNED:-1}"
    FORMULA_REPO_ENABLED="${FORMULA_REPO_ENABLED:-1}"

    FORMULA_REPO_PATH="$PPKG_FORMULA_REPO_ROOT/$FORMULA_REPO_NAME"

    if [ -d "$FORMULA_REPO_PATH" ] ; then
        abort 1 "$FORMULA_REPO_NAME named formula repository already exists."
    fi

    printf '%b\n' "${COLOR_PURPLE}==> Creating formula repository${COLOR_OFF} ${COLOR_GREEN}$FORMULA_REPO_NAME${COLOR_OFF}"

    SESSION_DIR="$PPKG_HOME/run/$$/$FORMULA_REPO_NAME"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR/formula"
    run cd         "$SESSION_DIR"

    run git -c init.defaultBranch=master init
    run git remote add origin "$FORMULA_REPO_URL"

    cat > .ppkg-formula-repo.yml <<EOF
url: $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $TIMESTAMP_UNIX
EOF

    run install -d        "$PPKG_FORMULA_REPO_ROOT"
    run mv "$SESSION_DIR" "$PPKG_FORMULA_REPO_ROOT/"
}

# }}}
##############################################################################
# {{{ ppkg formula-repo-del

# __delete_a_formula_repository <REPO-NAME>
  __delete_a_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."

    [ "$1" = 'official-core' ] && abort 1 "'official-core' formula repository is not allowed to delete."

    if [ -d    "$PPKG_FORMULA_REPO_ROOT/$1" ] ; then
        rm -rf "$PPKG_FORMULA_REPO_ROOT/$1"
    else
        warn "'$1' named formula repository does not exist."
    fi
}

# }}}
##############################################################################
# {{{ ppkg formula-repo-sync

# __sync_the_given_formula_repository <REPO-NAME>
  __sync_the_given_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."

    __load_formula_repository_config "$1"

    [ "$FORMULA_REPO_PINNED" = 1 ] && abort 1 "'$FORMULA_REPO_NAME' named formula repository is pinned."

    if [ -z "$PPKG_URL_TRANSFORM" ] ; then
        GIT_FETCH_URL="$FORMULA_REPO_URL"
    else
        GIT_FETCH_URL="$("$PPKG_URL_TRANSFORM" "$FORMULA_REPO_URL")"
    fi

    printf '%b\n' "${COLOR_PURPLE}==> Updating formula repository${COLOR_OFF} ${COLOR_GREEN}$FORMULA_REPO_NAME${COLOR_OFF}"

    run cd "$FORMULA_REPO_PATH"
    run git remote set-url origin "$GIT_FETCH_URL"
    run git -c protocol.version=2 fetch --progress origin "+refs/heads/$FORMULA_REPO_BRANCH:refs/remotes/origin/$FORMULA_REPO_BRANCH"
    run git checkout --progress --force -B "$FORMULA_REPO_BRANCH" "refs/remotes/origin/$FORMULA_REPO_BRANCH"

    cat > .ppkg-formula-repo.yml <<EOF
url: $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $FORMULA_REPO_TIMESTAMP_CREATED
updated: $TIMESTAMP_UNIX
EOF
}

# }}}
##############################################################################
# {{{ ppkg formula-repo-conf

# __conf_the_given_formula_repository <REPO-NAME> [--url=VALUE --branch=VALUE --pin/--unpin --enable/--disable]
  __conf_the_given_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."
    [ -z "$2" ] && abort 1 "at least one option should be given. supported options are: --url=VALUE --branch=VALUE --pin/--unpin --enable/--disable"

    __load_formula_repository_config "$1"

    shift

    while [ -n "$1" ]
    do
        case $1 in
            --url=*)
                FORMULA_REPO_URL="${1#*=}"

                if [ -z "$FORMULA_REPO_URL" ] ; then
                    abort 1 "--url=<VALUE> , <VALUE> should be non-empty."
                else
                    FORMULA_REPO_URL="$FORMULA_REPO_URL"
                fi
                ;;
            --branch=*)
                FORMULA_REPO_BRANCH="${1#*=}"

                if [ -z "$FORMULA_REPO_BRANCH" ] ; then
                    abort 1 "--branch=<VALUE> , <VALUE> should be non-empty."
                else
                    FORMULA_REPO_BRANCH="$FORMULA_REPO_BRANCH"
                fi
                ;;
            --pin)
                FORMULA_REPO_PINNED=1
                ;;
            --unpin)
                FORMULA_REPO_PINNED=0
                ;;
            --enable)
                FORMULA_REPO_ENABLED=1
                ;;
            --disable)
                FORMULA_REPO_ENABLED=0
                ;;
            *)  abort 1 "unrecognized argument: $1"
        esac
        shift
    done

    if [ -z "$FORMULA_REPO_TIMESTAMP_UPDATED" ] ; then
        cat > "$FORMULA_REPO_PATH/.ppkg-formula-repo.yml" <<EOF
url:  $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned:  $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $FORMULA_REPO_TIMESTAMP_CREATED
EOF
    else
        cat > "$FORMULA_REPO_PATH/.ppkg-formula-repo.yml" <<EOF
url:  $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned:  $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $FORMULA_REPO_TIMESTAMP_CREATED
updated: $FORMULA_REPO_TIMESTAMP_UPDATED
EOF
fi
}

# }}}
##############################################################################
# {{{ ppkg formula-repo-info

# __info_the_given_formula_repository <REPO-NAME>
  __info_the_given_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."

    __load_formula_repository_config "$1"

    cat <<EOF
name: $FORMULA_REPO_NAME
path: $FORMULA_REPO_PATH
url:  $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $(date -d "@$FORMULA_REPO_TIMESTAMP_CREATED" '+%Y-%m-%d %H:%M:%S%:z')
EOF

    if [ -n "$FORMULA_REPO_TIMESTAMP_UPDATED" ] ; then
        printf 'updated: %s\n' "$(date -d "@$FORMULA_REPO_TIMESTAMP_UPDATED" '+%Y-%m-%d %H:%M:%S%:z')"
    fi
}

# }}}
##############################################################################
# {{{ ppkg formula-repo-list

__list_available_formula_repositories() {
    [ -d "$PPKG_FORMULA_REPO_ROOT" ] || return 0

    I=0

    for item in $(cd "$PPKG_FORMULA_REPO_ROOT" && ls)
    do
        if [ -f "$PPKG_FORMULA_REPO_ROOT/$item/.ppkg-formula-repo.yml" ] ; then
            I="$(($I + 1))"

            [ "$I" -gt 1 ] && printf '\n'

            __info_the_given_formula_repository "$item"
        fi
    done
}

# }}}
##############################################################################
# {{{ ppkg update

__sync_available_formula_repositories() {
    [ -d "$PPKG_FORMULA_REPO_ROOT" ] && {
        for item in $(cd "$PPKG_FORMULA_REPO_ROOT" && ls)
        do
            if [ -f "$PPKG_FORMULA_REPO_ROOT/$item/.ppkg-formula-repo.yml" ] ; then
                __sync_the_given_formula_repository "$item"
            fi
        done
    }

    [ -d "$PPKG_FORMULA_REPO_ROOT/official-core" ] || {
        __create_a_formula_repository_then_sync_it official-core "$PPKG_OFFICIAL_FORMULA_REPO_URL"
    }
}

# __path_of_formula_of_the_given_package <PACKAGE-NAME>
  __path_of_formula_of_the_given_package() {
    [ -z "$1" ] && abort 1 "__path_of_formula_of_the_given_package <PACKAGE-NAME>, <PACKAGE-NAME> is unspecified."

    if [ -n "$PPKG_FORMULA_SEARCH_DIRS" ] ; then
        export IFS=':'

        for FORMULA_SEARCH_DIR in $PPKG_FORMULA_SEARCH_DIRS
        do
            FORMULA_FILEPATH="$FORMULA_SEARCH_DIR/$1.yml"

            if [ -f           "$FORMULA_FILEPATH" ] ; then
                printf '%s\n' "$FORMULA_FILEPATH"
                return 0
            fi
        done

        unset IFS
    fi

    [ -d "$PPKG_FORMULA_REPO_ROOT" ] || return 0

    AVAILABLE_FORMULA_REPOSITORY_NAMES=

    for item in $(cd "$PPKG_FORMULA_REPO_ROOT" && ls)
    do
        if [ -f "$PPKG_FORMULA_REPO_ROOT/$item/.ppkg-formula-repo.yml" ] ; then
            AVAILABLE_FORMULA_REPOSITORY_NAMES="$AVAILABLE_FORMULA_REPOSITORY_NAMES $item"
        fi
    done

    for FORMULA_REPOSITORY_NAME in $AVAILABLE_FORMULA_REPOSITORY_NAMES
    do
        if [ -e           "$PPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula/$TARGET_PLATFORM_NAME/$1.yml" ] ; then
            printf '%s\n' "$PPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula/$TARGET_PLATFORM_NAME/$1.yml"
            return 0
        fi

        if [ -e           "$PPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula/$1.yml" ] ; then
            printf '%s\n' "$PPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula/$1.yml"
            return 0
        fi
    done
}

# }}}
##############################################################################
# {{{ formula parse

filetype_from_url() {
    # remove query params
    URL="${1%%'?'*}"

    FNAME="${URL##*/}"

    case $FNAME in
        *.tar.gz|*.tgz)
            printf '%s\n' '.tgz'
            ;;
        *.tar.lz|*.tlz)
            printf '%s\n' '.tlz'
            ;;
        *.tar.xz|*.txz)
            printf '%s\n' '.txz'
            ;;
        *.tar.bz2|*.tbz2)
            printf '%s\n' '.tbz2'
            ;;
        *.*)printf '%s\n' ".${FNAME##*.}"
    esac
}

# __load_formula_of_the_given_package <PACKAGE-NAME> [FORMULA-FILEPATH]
  __load_formula_of_the_given_package() {
    if [ -z "$1" ] ; then
        abort 1 "__load_formula_of_the_given_package <PACKAGE-NAME> [FORMULA-FILEPATH], <PACKAGE-NAME> is unspecified."
    else
        PACKAGE_NAME="$1"
        PACKAGE_NAME_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')
    fi

    #########################################################################################

    if [ -z "$2" ] ; then
        PACKAGE_FORMULA_FILEPATH="$(__path_of_formula_of_the_given_package "$1")"

        if [ -z "$PACKAGE_FORMULA_FILEPATH" ] ; then
            abort 1 "package '$1' is not available."
        fi
    else
        PACKAGE_FORMULA_FILEPATH="$2"
    fi

    #########################################################################################

    unset PACKAGE_PKGTYPE

    unset PACKAGE_SUMMARY

    unset PACKAGE_LICENSE

    unset PACKAGE_VERSION
    unset PACKAGE_VERSION_MAJOR
    unset PACKAGE_VERSION_MINOR
    unset PACKAGE_VERSION_PATCH
    unset PACKAGE_VERSION_TWEAK

    unset PACKAGE_WEB_URL

    unset PACKAGE_GIT_URL
    unset PACKAGE_GIT_SHA
    unset PACKAGE_GIT_REF
    unset PACKAGE_GIT_NTH

    unset PACKAGE_SRC_URL
    unset PACKAGE_SRC_URI
    unset PACKAGE_SRC_SHA
    unset PACKAGE_SRC_FILENAME
    unset PACKAGE_SRC_FILETYPE
    unset PACKAGE_SRC_FILEPATH

    unset PACKAGE_FIX_URL
    unset PACKAGE_FIX_URI
    unset PACKAGE_FIX_SHA
    unset PACKAGE_FIX_OPT
    unset PACKAGE_FIX_FILENAME
    unset PACKAGE_FIX_FILETYPE
    unset PACKAGE_FIX_FILEPATH

    unset PACKAGE_RES_URL
    unset PACKAGE_RES_URI
    unset PACKAGE_RES_SHA
    unset PACKAGE_RES_FILENAME
    unset PACKAGE_RES_FILETYPE
    unset PACKAGE_RES_FILEPATH

    # space-separated    perl modules that are depended by this package when installing, which will be installed via cpan
    unset PACKAGE_DEP_PLM

    # space-separated python packages that are depended by this package when installing, which will be installed via pip3
    unset PACKAGE_DEP_PYM

    # space-separated   uppm packages that are depended by this package when installing, which will be installed via uppm
    unset PACKAGE_DEP_UPP

    # space-separated ppkg packages that are depended by this package when installing and/or runtime, which will be installed via ppkg
    unset PACKAGE_DEP_PKG
    unset PACKAGE_DEP_PKG_FOR_TARGET
    unset PACKAGE_DEP_PKG_FOR_MUSL

    # space-separated ppkg resources that are needed by this package
    unset PACKAGE_DEP_RES

    # space-separated ppkg pkg-config packages that are depended by this package while linking
    unset PACKAGE_DEP_LIB

    unset PACKAGE_PPFLAGS
    unset PACKAGE_CCFLAGS
    unset PACKAGE_XXFLAGS
    unset PACKAGE_LDFLAGS

    unset PACKAGE_DOFETCH
    unset PACKAGE_DO12345
    unset PACKAGE_DOPATCH
    unset PACKAGE_PREPARE
    unset PACKAGE_DOBUILD
    unset PACKAGE_DOTWEAK

    unset PACKAGE_PATCHES
    unset PACKAGE_RESLIST

    unset PACKAGE_BINDENV
    unset PACKAGE_WRAPPER
    unset PACKAGE_CAVEATS

    unset PACKAGE_BSYSTEM
    unset PACKAGE_BSYSTEM_MASTER

    unset PACKAGE_USE_BSYSTEM_GO
    unset PACKAGE_USE_BSYSTEM_GN
    unset PACKAGE_USE_BSYSTEM_WAF
    unset PACKAGE_USE_BSYSTEM_ZIG
    unset PACKAGE_USE_BSYSTEM_RAKE
    unset PACKAGE_USE_BSYSTEM_NINJA
    unset PACKAGE_USE_BSYSTEM_GMAKE
    unset PACKAGE_USE_BSYSTEM_CMAKE
    unset PACKAGE_USE_BSYSTEM_XMAKE
    unset PACKAGE_USE_BSYSTEM_MESON
    unset PACKAGE_USE_BSYSTEM_CARGO
    unset PACKAGE_USE_BSYSTEM_CABAL
    unset PACKAGE_USE_BSYSTEM_AUTOGENSH
    unset PACKAGE_USE_BSYSTEM_AUTOTOOLS
    unset PACKAGE_USE_BSYSTEM_CONFIGURE
    unset PACKAGE_USE_BSYSTEM_NETSURF

    # directory relative to $PACKAGE_WORKING_DIR/src, which contains build script such as autogen.sh, configure, Makefile, CMakeLists.txt, meson.build, Cargo.toml, xmake.lua, etc.
    unset PACKAGE_BSCRIPT

    # whether to build in build script directory, otherwise build in build dir
    unset PACKAGE_BINBSTD

    unset PACKAGE_LTOABLE

    # whether the installed files can be moved/copied to other locations
    unset PACKAGE_MOVABLE

    unset PACKAGE_LINKAGE
    unset PACKAGE_SUPPORT_BUILD_IN_PARALLEL

    unset PACKAGE_DEVELOPER

    #########################################################################################

    PACKAGE_PKGTYPE="$(yq '.pkgtype | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_LINKAGE="$(yq '.linkage | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_SUMMARY="$(yq '.summary | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_LICENSE="$(yq '.license | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_VERSION="$(yq '.version | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_WEB_URL="$(yq '.web-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_GIT_URL="$(yq '.git-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_GIT_SHA="$(yq '.git-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_GIT_REF="$(yq '.git-ref | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_GIT_NTH="$(yq '.git-nth | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_SRC_URL="$(yq '.src-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_SRC_URI="$(yq '.src-uri | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_SRC_SHA="$(yq '.src-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_FIX_URL="$(yq '.fix-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_FIX_URI="$(yq '.fix-uri | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_FIX_SHA="$(yq '.fix-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_FIX_OPT="$(yq '.fix-opt | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_RES_URL="$(yq '.res-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_RES_URI="$(yq '.res-uri | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_RES_SHA="$(yq '.res-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_DEP_PKG="$(yq '.dep-pkg | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DEP_RES="$(yq '.dep-res | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DEP_LIB="$(yq '.dep-lib | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DEP_UPP="$(yq '.dep-upp | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DEP_PYM="$(yq '.dep-pym | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DEP_PLM="$(yq '.dep-plm | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_BSYSTEM="$(yq '.bsystem | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_BSCRIPT="$(yq '.bscript | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_BINBSTD="$(yq '.binbstd | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_LTOABLE="$(yq '.ltoable | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_MOVABLE="$(yq '.movable | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_CCFLAGS="$(yq '.ccflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_XXFLAGS="$(yq '.xxflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_PPFLAGS="$(yq '.ppflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_LDFLAGS="$(yq '.ldflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_DOFETCH="$(yq '.dofetch | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DO12345="$(yq '.do12345 | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DOPATCH="$(yq '.dopatch | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_PREPARE="$(yq '.prepare | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DOBUILD="$(yq '.install | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DOTWEAK="$(yq '.dotweak | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_PATCHES="$(yq '.patches | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_RESLIST="$(yq '.reslist | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_BINDENV="$(yq '.bindenv | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_WRAPPER="$(yq '.wrapper | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_CAVEATS="$(yq '.caveats | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_SUPPORT_BUILD_IN_PARALLEL="$(yq '.parallel | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_DEVELOPER="$(yq '.developer | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_DEP_PKG_FOR_TARGET="$(yq ".dep-pkg-$TARGET_PLATFORM_NAME | select(. != null)" "$PACKAGE_FORMULA_FILEPATH")"

    if [ -n "$PACKAGE_DEP_PKG_FOR_TARGET" ] ; then
        if [ -n "$PACKAGE_DEP_PKG" ] ; then
            PACKAGE_DEP_PKG="$PACKAGE_DEP_PKG $PACKAGE_DEP_PKG_FOR_TARGET"
        else
            PACKAGE_DEP_PKG="$PACKAGE_DEP_PKG_FOR_TARGET"
        fi
    fi

    if [ "$TARGET_PLATFORM_NAME" = linux ] && [ "$TARGET_PLATFORM_VERS" = musl ] ; then
        PACKAGE_DEP_PKG_FOR_MUSL="$(yq '.dep-pkg-musl | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

        if [ -n "$PACKAGE_DEP_PKG_FOR_MUSL" ] ; then
            if [ -n "$PACKAGE_DEP_PKG" ] ; then
                PACKAGE_DEP_PKG="$PACKAGE_DEP_PKG $PACKAGE_DEP_PKG_FOR_MUSL"
            else
                PACKAGE_DEP_PKG="$PACKAGE_DEP_PKG_FOR_MUSL"
            fi
        fi
    fi

    #########################################################################################

    if [ -z "$PACKAGE_SUMMARY" ] ; then
        abort 1 "summary mapping not found in $PACKAGE_FORMULA_FILEPATH"
    fi

    if [ -n "$PACKAGE_FIX_URL" ] && [ -n "$PACKAGE_PATCHES" ] ; then
        abort 1 "fix-url and patches mapping shouldn't be used together in $PACKAGE_FORMULA_FILEPATH"
    fi

    if [ -n "$PACKAGE_RES_URL" ] && [ -n "$PACKAGE_RESLIST" ] ; then
        abort 1 "res-url and reslist mapping shouldn't be used together in $PACKAGE_FORMULA_FILEPATH"
    fi

    if [ -n "$PACKAGE_GIT_NTH" ] ; then
        isInteger "$PACKAGE_GIT_NTH" || abort "the value of git-nth mapping should be an integer."
    fi

    #########################################################################################

    unset PACKAGE_NEED_CURL
    unset PACKAGE_NEED_BTAR

    #########################################################################################

    if [ -n "$PACKAGE_SRC_URL" ] ; then
        case $PACKAGE_SRC_URL in
            dir://*)
                PACKAGE_SRC_FILETYPE=.dir
                PACKAGE_SRC_FILEPATH=$(printf '%s\n' "$PACKAGE_SRC_URL" | cut -c7-)

                if [ -z "$PACKAGE_VERSION" ] ; then
                    PACKAGE_VERSION="$(date -u -d "@$TIMESTAMP_UNIX" '+%Y.%m.%d')"
                fi
                ;;
            file://*)
                PACKAGE_SRC_FILEPATH=$(printf '%s\n' "$PACKAGE_SRC_URL" | cut -c8-)
                PACKAGE_SRC_FILENAME="$(basename "$PACKAGE_SRC_FILEPATH")"
                PACKAGE_SRC_FILETYPE="$(filetype_from_url "$PACKAGE_SRC_FILENAME")"

                if [ -z "$PACKAGE_VERSION" ] ; then
                    PACKAGE_VERSION="$(date -u -d "@$TIMESTAMP_UNIX" '+%Y.%m.%d')"
                fi
                ;;
            *)  PACKAGE_SRC_FILETYPE="$(filetype_from_url "$PACKAGE_SRC_URL")"
                PACKAGE_SRC_FILENAME="$PACKAGE_SRC_SHA$PACKAGE_SRC_FILETYPE"
                PACKAGE_SRC_FILEPATH="$PPKG_DOWNLOADS_DIR/$PACKAGE_SRC_FILENAME"

                if [ -z "$PACKAGE_SRC_SHA" ] ; then
                    abort 1 "src-sha mapping not found in $PACKAGE_FORMULA_FILEPATH"
                fi

                if [ -z "$PACKAGE_GIT_URL" ] ; then
                    case $PACKAGE_SRC_URL in
                        https://github.com/*/*/releases/*)
                            PACKAGE_GIT_URL="${PACKAGE_SRC_URL%%/releases/*}"
                            ;;
                        https://github.com/*/*/archive/*)
                            PACKAGE_GIT_URL="${PACKAGE_SRC_URL%%/archive/*}"
                            ;;
                        https://gitlab.com/*/*/-/archive/*)
                            PACKAGE_GIT_URL="${PACKAGE_SRC_URL%%/-/archive/*}"
                            ;;
                    esac
                fi

                if [ -z "$PACKAGE_VERSION" ] ; then
                    PACKAGE_VERSION="$(basename "$PACKAGE_SRC_URL" | tr '_@' - | sed -e 's|\.tar\.[glx]z$||' -e 's|\.tar\.bz2$||' -e 's|\.t[glx]z$||' -e 's|\.zip$||' -e 's|-stable||' -e 's|-source||' -e 's|[-.]src$||' -e 's|\.orig||' -e 's|\.crate||' | awk -F- '{print $NF}')"
                    case $PACKAGE_VERSION in
                        '') abort 1 "version mapping not found in $PACKAGE_FORMULA_FILEPATH" ;;
                        v*) PACKAGE_VERSION="${PACKAGE_VERSION#v}"
                    esac
                fi

                PACKAGE_NEED_CURL=1

                case $PACKAGE_SRC_FILETYPE in
                    .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                        PACKAGE_NEED_BTAR=1
                esac
        esac
    else
        if [ -n "$PACKAGE_GIT_URL" ] ; then
            PACKAGE_SRC_FILETYPE=.git
            PACKAGE_SRC_FILEPATH=.git

            if [ -z "$PACKAGE_VERSION" ] && [ -z "$PACKAGE_GIT_SHA" ] && [ -n "$PACKAGE_GIT_REF" ] ; then
                PACKAGE_GIT_REF_NAME="${PACKAGE_GIT_REF##*/}"

                case $PACKAGE_GIT_REF_NAME in
                    v*) PACKAGE_VERSION="${PACKAGE_GIT_REF_NAME#v}" ;;
                    [0-9]*) PACKAGE_VERSION="$PACKAGE_GIT_REF_NAME"
                esac
            fi

            if [ -z "$PACKAGE_VERSION" ] ; then
                PACKAGE_VERSION="$(date -u -d "@$TIMESTAMP_UNIX" '+%Y.%m.%d')"
            fi

            PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP git"
        fi
    fi

    #########################################################################################

    if [ -z "$PACKAGE_WEB_URL" ] && [ -z "$PACKAGE_GIT_URL" ] ; then
        abort 1 "neither web-url nor git-url mapping was found in $PACKAGE_FORMULA_FILEPATH"
    fi

    #########################################################################################

    [ -n "$PACKAGE_FIX_URL" ] && {
        [ -z "$PACKAGE_FIX_SHA" ] && abort 1 "fix-sha mapping not found in $PACKAGE_FORMULA_FILEPATH"

        PACKAGE_FIX_FILETYPE="$(filetype_from_url "$PACKAGE_FIX_URL")"
        PACKAGE_FIX_FILENAME="$PACKAGE_FIX_SHA$PACKAGE_FIX_FILETYPE"
        PACKAGE_FIX_FILEPATH="$PPKG_DOWNLOADS_DIR/$PACKAGE_FIX_FILENAME"

        PACKAGE_NEED_CURL=1

        case $PACKAGE_FIX_FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                PACKAGE_NEED_BTAR=1
        esac
    }

    #########################################################################################

    [ -n "$PACKAGE_RES_URL" ] && {
        [ -z "$PACKAGE_RES_SHA" ] && abort 1 "res-sha mapping not found in $PACKAGE_FORMULA_FILEPATH"

        PACKAGE_RES_FILETYPE="$(filetype_from_url "$PACKAGE_RES_URL")"
        PACKAGE_RES_FILENAME="$PACKAGE_RES_SHA$PACKAGE_RES_FILETYPE"
        PACKAGE_RES_FILEPATH="$PPKG_DOWNLOADS_DIR/$PACKAGE_RES_FILENAME"

        PACKAGE_NEED_CURL=1

        case $PACKAGE_RES_FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                PACKAGE_NEED_BTAR=1
        esac
    }

    #########################################################################################

    for LINE in $PACKAGE_PATCHES $PACKAGE_RESLIST
    do
        SHA="$(printf '%s\n' "$LINE" | cut -d '|' -f1)"
        URL="$(printf '%s\n' "$LINE" | cut -d '|' -f2)"

        FILETYPE="$(filetype_from_url "$URL")"

        if [ "${#SHA}" -ne 64 ] ; then
            abort 1 "not a sha256sum in line: $LINE in file: $PACKAGE_FORMULA_FILEPATH"
        fi

        PACKAGE_NEED_CURL=1

        case $FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                PACKAGE_NEED_BTAR=1
        esac
    done

    #########################################################################################

    [ "$PACKAGE_NEED_CURL" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP curl"
    [ "$PACKAGE_NEED_BTAR" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP bsdtar"

    #########################################################################################

    [ -n "$PACKAGE_VERSION" ] && {
        PACKAGE_VERSION_MAJOR="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f1)"
        PACKAGE_VERSION_MINOR="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f2)"
        PACKAGE_VERSION_PATCH="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f3)"
        PACKAGE_VERSION_TWEAK="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f4)"
    }

    #########################################################################################

    if [     -z "$PACKAGE_BSYSTEM" ] ; then
        if [ -z "$PACKAGE_DOBUILD" ] ; then
            abort 1 "neither bsystem nor install mapping was found in $PACKAGE_FORMULA_FILEPATH"
        else
            for FirstWordOfLineInInstallActions in $(printf '%s\n' "$PACKAGE_DOBUILD" | sed 's|^[[:space:]]*||' | cut -d ' ' -f1)
            do
                case "$FirstWordOfLineInInstallActions" in
                    configure)    PACKAGE_BSYSTEM=configure ; break ;;
                    cmakew)       PACKAGE_BSYSTEM=cmake ; break ;;
                    xmakew)       PACKAGE_BSYSTEM=xmake ; break ;;
                    mesonw)       PACKAGE_BSYSTEM=meson ; break ;;
                    gmakew)       PACKAGE_BSYSTEM=gmake ; break ;;
                    cargow)       PACKAGE_BSYSTEM=cargo ; break ;;
                    go|gow)       PACKAGE_BSYSTEM=go    ; break ;;
                    waf)          PACKAGE_BSYSTEM=waf   ; break ;;
                    zig)          PACKAGE_BSYSTEM=zig   ; break ;;
                    cabal_v2_install)
                                  PACKAGE_BSYSTEM=cabal ; break ;;
                esac
            done
        fi
    fi

    PACKAGE_BSYSTEM_MASTER="${PACKAGE_BSYSTEM%%' '*}"

    #########################################################################################

    for BSTSTEM in $PACKAGE_BSYSTEM
    do
        case $BSTSTEM in
            autogen)     PACKAGE_USE_BSYSTEM_AUTOGENSH=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            autotools)   PACKAGE_USE_BSYSTEM_AUTOTOOLS=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            configure)   PACKAGE_USE_BSYSTEM_CONFIGURE=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            cmake+gmake) PACKAGE_USE_BSYSTEM_CMAKE=1     ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            cmake+ninja) PACKAGE_USE_BSYSTEM_CMAKE=1     ; PACKAGE_USE_BSYSTEM_NINJA=1 ;;
            cmake)       PACKAGE_USE_BSYSTEM_CMAKE=1     ; PACKAGE_USE_BSYSTEM_NINJA=1 ;;
            xmake)       PACKAGE_USE_BSYSTEM_XMAKE=1     ;;
            meson)       PACKAGE_USE_BSYSTEM_MESON=1     ; PACKAGE_USE_BSYSTEM_NINJA=1 ;;
            ninja)       PACKAGE_USE_BSYSTEM_NINJA=1     ;;
            gmake)       PACKAGE_USE_BSYSTEM_GMAKE=1     ;;
            netsurf)     PACKAGE_USE_BSYSTEM_GMAKE=1     ; PACKAGE_USE_BSYSTEM_NETSURF=1 ;;
            rake)        PACKAGE_USE_BSYSTEM_RAKE=1      ;;
            cargo)       PACKAGE_USE_BSYSTEM_CARGO=1     ;;
            cabal)       PACKAGE_USE_BSYSTEM_CABAL=1     ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            go)          PACKAGE_USE_BSYSTEM_GO=1        ;;
            gn)          PACKAGE_USE_BSYSTEM_GN=1        ;;
            waf)         PACKAGE_USE_BSYSTEM_WAF=1       ;;
            zig)         PACKAGE_USE_BSYSTEM_ZIG=1       ;;
            zig@[0-9].[0-9][0-9])
                         PACKAGE_USE_BSYSTEM_ZIG=1       ;;
        esac
    done

    #########################################################################################

    [ -z "$PACKAGE_DOBUILD" ] && {
        case $PACKAGE_BSYSTEM_MASTER in
            autogen)   PACKAGE_DOBUILD='configure' ;;
            autotools) PACKAGE_DOBUILD='configure' ;;
            configure) PACKAGE_DOBUILD='configure' ;;
            netsurf)   PACKAGE_DOBUILD='netsurf_buildsystem' ;;
            cmake*)    PACKAGE_DOBUILD='cmakew' ;;
            xmake)     PACKAGE_DOBUILD='xmakew' ;;
            meson)     PACKAGE_DOBUILD='mesonw' ;;
            ninja)     PACKAGE_DOBUILD='ninjaw clean && ninjaw && ninjaw install' ;;
            gmake)     PACKAGE_DOBUILD='gmakew clean && gmakew && gmakew install' ;;
            cargo)     PACKAGE_DOBUILD='cargow install' ;;
            cabal)     PACKAGE_DOBUILD='cabal_v2_install' ;;
            go)        PACKAGE_DOBUILD='gow' ;;
            gn)        PACKAGE_DOBUILD='gnw' ;;
            waf)       PACKAGE_DOBUILD='waf' ;;
            zig)       PACKAGE_DOBUILD='zig' ;;
            zig@[0-9].[0-9][0-9])
                       PACKAGE_DOBUILD='zig' ;;
        esac
    }

    #########################################################################################

    if [ -n "$PACKAGE_FIX_URL" ] || [ -n "$PACKAGE_PATCHES" ] ; then
        PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP patch"
    fi

    [ -n "$PACKAGE_DEP_PYM" ]                && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3"
    [ -n "$PACKAGE_DEP_PLM" ]                && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl gmake"

    [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake gm4 perl autoconf automake"
    [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake gm4 perl autoconf automake"
    [ "$PACKAGE_USE_BSYSTEM_CONFIGURE" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake"
    [ "$PACKAGE_USE_BSYSTEM_NETSURF"   = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake netsurf_buildsystem"
    [ "$PACKAGE_USE_BSYSTEM_MESON"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3"
    [ "$PACKAGE_USE_BSYSTEM_MESON"     = 1 ] && PACKAGE_DEP_PYM="$PACKAGE_DEP_PYM meson"
    [ "$PACKAGE_USE_BSYSTEM_CMAKE"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP cmake"
    [ "$PACKAGE_USE_BSYSTEM_GMAKE"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake"
    [ "$PACKAGE_USE_BSYSTEM_XMAKE"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP xmake"
    [ "$PACKAGE_USE_BSYSTEM_NINJA"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP ninja"
    [ "$PACKAGE_USE_BSYSTEM_RAKE"      = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP ruby"
    [ "$PACKAGE_USE_BSYSTEM_GO"        = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP golang"
    [ "$PACKAGE_USE_BSYSTEM_WAF"       = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3"
    [ "$PACKAGE_USE_BSYSTEM_ZIG"       = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP $PACKAGE_BSYSTEM"

    [ "$PACKAGE_USE_BSYSTEM_CABAL"     = 1 ] && PACKAGE_DEP_PKG="$PACKAGE_DEP_PKG libncurses libffi libgmp libz"

    #########################################################################################

    [ "$PACKAGE_USE_BSYSTEM_WAF"   = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_ZIG"   = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_GO"    = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_XMAKE" = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_CABAL" = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_NETSURF" = 1 ] && PACKAGE_BINBSTD=1

    if [ -z  "$PACKAGE_BINBSTD" ] ; then
        if [ "$PACKAGE_BSYSTEM_MASTER" = gmake ] ; then
            PACKAGE_BINBSTD=1
        else
            PACKAGE_BINBSTD=0
        fi
    fi

    #########################################################################################

    PACKAGE_DEP_UPP="${PACKAGE_DEP_UPP#' '}"

    #########################################################################################

    if [ -z "$PACKAGE_PKGTYPE" ] ; then
        case $PACKAGE_NAME in
            lib*)   PACKAGE_PKGTYPE=lib ;;
            *lib)   PACKAGE_PKGTYPE=lib ;;
            *-dev)  PACKAGE_PKGTYPE=lib ;;
            xorg-lib*)
                    PACKAGE_PKGTYPE=lib ;;
               *)   PACKAGE_PKGTYPE=exe ;;
        esac
    fi

    #########################################################################################

    [ -z "$PACKAGE_LTOABLE" ] && PACKAGE_LTOABLE=1
    [ -z "$PACKAGE_MOVABLE" ] && PACKAGE_MOVABLE=1
    [ -z "$PACKAGE_SUPPORT_BUILD_IN_PARALLEL" ] && PACKAGE_SUPPORT_BUILD_IN_PARALLEL=1

    #########################################################################################

    if [ "$PACKAGE_PKGTYPE" = exe ] ; then
        case $PACKAGE_LINKAGE in
            ''|static|static/pie|shared|shared/most) ;;
            *)  abort 1 "unsupported linkage: $PACKAGE_LINKAGE"
        esac
    fi
}

# }}}
##############################################################################
# {{{ ppkg is-available

# check if the given package is available
# if the version condition is given, check if the condition is matched
#
# condition operator:
# eq  equal
# ne  not equal
# gt  greater than
# lt  less than
# ge  greater than or equal
# le  less than or equal
#
# examples:
# is_package_available automake eq 1.16.0
# is_package_available automake lt 1.16.0
# is_package_available automake gt 1.16.0
# is_package_available automake le 1.16.0
# is_package_available automake ge 1.16.0
# is_package_available automake
  is_package_available() {
    [ -z "$1" ] && abort 1 "is_package_available <PACKAGE-NAME> [<eq|lt|gt|le|ge> <VERSION>], <PACKAGE-NAME> is unspecified."

    case $# in
        1)  [ -n "$(__path_of_formula_of_the_given_package "$1" || true)" ] ;;
        3)  __load_formula_of_the_given_package "$1" || return 1
            shift
            version_match "$PACKAGE_VERSION" "$@"
            ;;
        *)  abort 1 "is available command only accept 1 or 3 argument."
    esac
}

# }}}
##############################################################################
# {{{ ppkg is-installed

# is_package_installed <PACKAGE-SPEC>
  is_package_installed() {
    [ -z "$1" ] && abort 1 "is_package_installed <PACKAGE-SPEC>, <PACKAGE-SPEC> is unspecified."

    [ -d "$PPKG_PACKAGE_INSTALLED_ROOT/$1" ]                    || return 10
    [ -d "$PPKG_PACKAGE_INSTALLED_ROOT/$1/.ppkg" ]              || return 11
    [ -f "$PPKG_PACKAGE_INSTALLED_ROOT/$1/.ppkg/MANIFEST.txt" ] || return 13
    [ -f "$PPKG_PACKAGE_INSTALLED_ROOT/$1/.ppkg/RECEIPT.yml" ]  || return 14
}

# }}}
##############################################################################
# {{{ ppkg is-symlinked

# is_package_symlinked <PACKAGE-SPEC>
  is_package_symlinked() {
    is_package_installed "$1" && [ -f "$PPKG_PACKAGE_SYMLINKED_ROOT/.registry/$1" ]
}

# }}}
##############################################################################
# {{{ ppkg is-outdated

# is_package__outdated <PACKAGE-SPEC>
  is_package__outdated() {
    __load_formula_of_the_given_package "${1##*/}"
    __load_receipt_of_the_given_package "$1"
    version_match "$PACKAGE_VERSION" gt "$RECEIPT_PACKAGE_VERSION"
}

# }}}
##############################################################################
# {{{ ppkg ls-installed

__list_installed_packages() {
    if [  -d "$PPKG_PACKAGE_INSTALLED_ROOT" ] ; then
        find "$PPKG_PACKAGE_INSTALLED_ROOT" -maxdepth 2 -mindepth 2 -type l -printf '%P\n'
    else
        return 0
    fi
}

# }}}
##############################################################################
# {{{ ppkg ls-available [-v] [--yaml | --json]

__list_available_packages() {
    unset OUTPUT_MODE
    unset OUTPUT_TYPE

    for arg in $@
    do
        case $arg in
            -v)     OUTPUT_MODE=full ;;
            --json) OUTPUT_TYPE=json ;;
            --yaml) OUTPUT_TYPE=yaml ;;
            *) abort 1 "unrecognized argument: $arg"
        esac
    done

    if [ -z "$OUTPUT_MODE" ] ; then
        __list_available_package_names
    else
        AVAILABLE_PACKAGE_NAMES="$(__list_available_package_names)"

        [ -z "$AVAILABLE_PACKAGE_NAMES" ] && return 0

        IS_FIRST_ELEMENT=1

        case $OUTPUT_TYPE in
            yaml|'')
                for PKGNAME in $AVAILABLE_PACKAGE_NAMES
                do
                    if [ "$IS_FIRST_ELEMENT" = 1 ] ; then
                        unset IS_FIRST_ELEMENT
                    else
                        printf '%s\n' '---'
                    fi
                    __info_the_given_available_package_as_yaml "$PKGNAME"
                done
                ;;
            json)
                printf '%s\n' '['

                for PKGNAME in $AVAILABLE_PACKAGE_NAMES
                do
                    if [ "$IS_FIRST_ELEMENT" = 1 ] ; then
                        unset IS_FIRST_ELEMENT
                    else
                        printf '%s\n' ','
                    fi
                    __info_the_given_available_package_as_json "$PKGNAME"
                done

                printf '%s\n' ']'
                ;;
        esac
    fi
}

__list_available_package_names() {
    [ -d "$PPKG_FORMULA_REPO_ROOT" ] || return 0

    {
        FORMULA_REPOSITORY_NAMES=

        for item in $(cd "$PPKG_FORMULA_REPO_ROOT" && ls)
        do
            if [ -f "$PPKG_FORMULA_REPO_ROOT/$item/.ppkg-formula-repo.yml" ] ; then
                FORMULA_REPOSITORY_NAMES="$FORMULA_REPOSITORY_NAMES $item"
            fi
        done

        for FORMULA_REPOSITORY_NAME in $FORMULA_REPOSITORY_NAMES
        do
            FORMULA_SEARCH_DIR="$PPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula/$TARGET_PLATFORM_NAME"

            if [ -d  "$FORMULA_SEARCH_DIR" ] ; then
                find "$FORMULA_SEARCH_DIR" -maxdepth 1 -type f -name '*.yml' -printf '%P\n'
            fi

            FORMULA_SEARCH_DIR="$PPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula"

            if [ -d  "$FORMULA_SEARCH_DIR" ] ; then
                find "$FORMULA_SEARCH_DIR" -maxdepth 1 -type f -name '*.yml' -printf '%P\n'
            fi
        done
    } | sed 's|\.yml$||' | sort | uniq
}

# }}}
##############################################################################
# {{{ ppkg ls-symlinked

__list_symlinked_packages() {
    if [ -d "$PPKG_PACKAGE_SYMLINKED_ROOT/.registry" ] ; then
         cd "$PPKG_PACKAGE_SYMLINKED_ROOT/.registry" || return 1
    else
        return 0
    fi

    ls -1
}

# }}}
##############################################################################
# {{{ ppkg ls-outdated

__list__outdated_packages() {
    [ -d "$PPKG_PACKAGE_INSTALLED_ROOT" ] || return 0

    for pkg in $(find "$PPKG_PACKAGE_INSTALLED_ROOT" -maxdepth 2 -mindepth 2 -type l -printf '%P\n')
    do
        if is_package__outdated "$pkg" ; then
            printf '%s\n' "$pkg"
        fi
    done
}

# }}}
##############################################################################
# {{{ ppkg search <REGULAR-EXPRESSION-PATTERN> [-v]

__search_packages() {
    [ -z "$1" ] && abort 1 "please specify a regular express pattern."

    AVAILABLE_PACKAGE_NAMES_ALL="$(__list_available_package_names)"

    [ -z "$AVAILABLE_PACKAGE_NAMES_ALL" ] && return 0

    AVAILABLE_PACKAGE_NAMES_FILTERED="$(printf '%s\n' $AVAILABLE_PACKAGE_NAMES_ALL | grep "$1" || true)"

    [ -z "$AVAILABLE_PACKAGE_NAMES_FILTERED" ] && return 0

    case $2 in
        '') printf '%s\n' $AVAILABLE_PACKAGE_NAMES_FILTERED ;;
        -v) IS_FIRST_ELEMENT=1

            for PKGNAME in $AVAILABLE_PACKAGE_NAMES_FILTERED
            do
                if [ "$IS_FIRST_ELEMENT" = 1 ] ; then
                    unset IS_FIRST_ELEMENT
                else
                    printf '%s\n' '---'
                fi

                __info_the_given_available_package_as_yaml "$PKGNAME"
            done
            ;;
        *)  abort 1 "unrecognzied argument: $2"
    esac
}

# }}}
##############################################################################
# {{{ ppkg info

# __info_the_given_available_package_as_json <PACKAGE-NAME>
  __info_the_given_available_package_as_json() {
    __load_formula_of_the_given_package "$1"

    if [ -z "$PACKAGE_WEB_URL" ] ; then
        PACKAGE_WEB_URL="$PACKAGE_GIT_URL"
    fi

    jq  --null-input \
        --arg pkgname "$PACKAGE_NAME" \
        --arg pkgtype "$PACKAGE_PKGTYPE" \
        --arg version "$PACKAGE_VERSION" \
        --arg summary "$PACKAGE_SUMMARY" \
        --arg license "$PACKAGE_LICENSE" \
        --arg web_url "$PACKAGE_WEB_URL" \
        --arg git_url "$PACKAGE_GIT_URL" \
        --arg git_sha "$PACKAGE_GIT_SHA" \
        --arg git_ref "$PACKAGE_GIT_REF" \
        --arg git_nth "$PACKAGE_GIT_NTH" \
        --arg src_url "$PACKAGE_SRC_URL" \
        --arg src_uri "$PACKAGE_SRC_URI" \
        --arg src_sha "$PACKAGE_SRC_SHA" \
        --arg fix_url "$PACKAGE_FIX_URL" \
        --arg fix_uri "$PACKAGE_FIX_URI" \
        --arg fix_sha "$PACKAGE_FIX_SHA" \
        --arg res_url "$PACKAGE_RES_URL" \
        --arg res_uri "$PACKAGE_RES_URI" \
        --arg res_sha "$PACKAGE_RES_SHA" \
        --arg patches "$PACKAGE_PATCHES" \
        --arg reslist "$PACKAGE_RESLIST" \
        --arg dep_pkg "$PACKAGE_DEP_PKG" \
        --arg dep_res "$PACKAGE_DEP_RES" \
        --arg dep_lib "$PACKAGE_DEP_LIB" \
        --arg dep_upp "$PACKAGE_DEP_UPP" \
        --arg dep_pym "$PACKAGE_DEP_PYM" \
        --arg dep_plm "$PACKAGE_DEP_PLM" \
        --arg dofetch "$PACKAGE_DOFETCH" \
        --arg ltoable "$PACKAGE_LTOABLE" \
        --arg movable "$PACKAGE_MOVABLE" \
        --arg do12345 "$PACKAGE_DO12345" \
        --arg dopatch "$PACKAGE_DOPATCH" \
        --arg prepare "$PACKAGE_PREPARE" \
        --arg install "$PACKAGE_DOBUILD" \
        --arg dotweak "$PACKAGE_DOTWEAK" \
        --arg bindenv "$PACKAGE_BINDENV" \
        --arg caveats "$PACKAGE_CAVEATS" \
        --arg bsystem "$PACKAGE_BSYSTEM" \
        --arg binbstd "$PACKAGE_BINBSTD" \
        --arg ccflags "$PACKAGE_CCFLAGS" \
        --arg xxflags "$PACKAGE_XXFLAGS" \
        --arg ppflags "$PACKAGE_PPFLAGS" \
        --arg ldflags "$PACKAGE_LDFLAGS" \
        --arg parallel $PACKAGE_SUPPORT_BUILD_IN_PARALLEL \
        --arg developer "$PACKAGE_DEVELOPER" \
'{
    "pkgname":$pkgname,
    "pkgtype":$pkgtype,
    "version":$version,
    "license":$license,
    "summary":$summary,
    "web-url":$web_url,
    "git-url":$git_url,
    "git-sha":$git_sha,
    "git-ref":$git_ref,
    "git-nth":$git_nth,
    "src-url":$src_url,
    "src-uri":$src_uri,
    "src-sha":$src_sha,
    "fix-url":$fix_url,
    "fix-uri":$fix_uri,
    "fix-sha":$fix_sha,
    "res-url":$res_url,
    "res-uri":$res_uri,
    "res-sha":$res_sha,
    "patches":$patches,
    "reslist":$reslist,
    "dep-pkg":$dep_pkg,
    "dep-res":$dep_res,
    "dep-lib":$dep_lib,
    "dep-upp":$dep_upp,
    "dep-pym":$dep_pym,
    "dep-plm":$dep_plm,
    "bsystem":$bsystem,
    "binbstd":$binbstd,
    "ccflags":$ccflags,
    "xxflags":$xxflags,
    "ppflags":$ppflags,
    "ldflags":$ldflags,
    "parallel":$parallel,
    "developer":$developer,
    "dofetch":$dofetch,
    "ltoable":$ltoable,
    "movable":$movable,
    "do12345":$do12345,
    "dopatch":$dopatch,
    "prepare":$prepare,
    "install":$install,
    "dotweak":$dotweak,
    "bindenv":$bindenv,
    "caveats":$caveats
}' | jq 'with_entries(select(.value != ""))'
}

# __info_the_given_available_package_as_yaml <PACKAGE-NAME>
  __info_the_given_available_package_as_yaml() {
    __load_formula_of_the_given_package "$1"

    if [ -z "$PACKAGE_WEB_URL" ] ; then
        PACKAGE_WEB_URL="$PACKAGE_GIT_URL"
    fi

    if is_package_installed "$1" ; then
        PACKAGE_INSTALLED=yes
    else
        PACKAGE_INSTALLED=no
    fi

    {
    cat <<EOF
pkgname: $PACKAGE_NAME
pkgtype: $PACKAGE_PKGTYPE
version: $PACKAGE_VERSION
license: $PACKAGE_LICENSE
summary: $PACKAGE_SUMMARY
web-url: $PACKAGE_WEB_URL
git-url: $PACKAGE_GIT_URL
git-sha: $PACKAGE_GIT_SHA
git-ref: $PACKAGE_GIT_REF
git-nth: $PACKAGE_GIT_NTH
src-url: $PACKAGE_SRC_URL
src-uri: $PACKAGE_SRC_URI
src-sha: $PACKAGE_SRC_SHA
fix-url: $PACKAGE_FIX_URL
fix-uri: $PACKAGE_FIX_URI
fix-sha: $PACKAGE_FIX_SHA
res-url: $PACKAGE_RES_URL
res-uri: $PACKAGE_RES_URI
res-sha: $PACKAGE_RES_SHA
dep-pkg: $PACKAGE_DEP_PKG
dep-res: $PACKAGE_DEP_RES
dep-lib: $PACKAGE_DEP_LIB
dep-upp: $PACKAGE_DEP_UPP
dep-pym: $PACKAGE_DEP_PYM
dep-plm: $PACKAGE_DEP_PLM
bsystem: $PACKAGE_BSYSTEM
binbstd: $PACKAGE_BINBSTD
ppflags: $PACKAGE_PPFLAGS
ccflags: $PACKAGE_CCFLAGS
xxflags: $PACKAGE_XXFLAGS
ldflags: $PACKAGE_LDFLAGS
parallel: $PACKAGE_SUPPORT_BUILD_IN_PARALLEL
installed: $PACKAGE_INSTALLED
EOF
    } | yq eval '. | with_entries(select(.value != null))'
}

# __info_the_given_available_package_as_shell <PACKAGE-NAME>
  __info_the_given_available_package_as_shell() {
    __load_formula_of_the_given_package "$1"

    while read KEY
    do
        printf "%s='%s'\n" "${PACKAGE_NAME_UPPERCASE_UNDERSCORE}_${KEY}" "$(eval echo \$$KEY)"
    done <<EOF
PACKAGE_NAME
PACKAGE_PKGTYPE
PACKAGE_SUMMARY
PACKAGE_LICENSE
PACKAGE_VERSION
PACKAGE_VERSION_MAJOR
PACKAGE_VERSION_MINOR
PACKAGE_VERSION_PATCH
PACKAGE_VERSION_TWEAK
PACKAGE_WEB_URL
PACKAGE_GIT_URL
PACKAGE_GIT_SHA
PACKAGE_GIT_REF
PACKAGE_GIT_NTH
PACKAGE_SRC_URL
PACKAGE_SRC_URI
PACKAGE_SRC_SHA
PACKAGE_SRC_FILETYPE
PACKAGE_SRC_FILENAME
PACKAGE_SRC_FILEPATH
PACKAGE_FIX_URL
PACKAGE_FIX_URI
PACKAGE_FIX_SHA
PACKAGE_FIX_FILETYPE
PACKAGE_FIX_FILENAME
PACKAGE_FIX_FILEPATH
PACKAGE_RES_URL
PACKAGE_RES_URI
PACKAGE_RES_SHA
PACKAGE_RES_FILETYPE
PACKAGE_RES_FILENAME
PACKAGE_RES_FILEPATH
PACKAGE_BSCRIPT
PACKAGE_BSYSTEM
PACKAGE_BINBSTD
PACKAGE_USE_BSYSTEM_GO
PACKAGE_USE_BSYSTEM_WAF
PACKAGE_USE_BSYSTEM_RAKE
PACKAGE_USE_BSYSTEM_NINJA
PACKAGE_USE_BSYSTEM_GMAKE
PACKAGE_USE_BSYSTEM_CMAKE
PACKAGE_USE_BSYSTEM_XMAKE
PACKAGE_USE_BSYSTEM_MESON
PACKAGE_USE_BSYSTEM_CARGO
PACKAGE_USE_BSYSTEM_CABAL
PACKAGE_USE_BSYSTEM_AUTOGENSH
PACKAGE_USE_BSYSTEM_AUTOTOOLS
PACKAGE_USE_BSYSTEM_CONFIGURE
PACKAGE_DEP_PKG
PACKAGE_DEP_RES
PACKAGE_DEP_LIB
PACKAGE_DEP_UPP
PACKAGE_DEP_PYM
PACKAGE_DEP_PLM
PACKAGE_CCFLAGS
PACKAGE_XXFLAGS
PACKAGE_PPFLAGS
PACKAGE_LDFLAGS
PACKAGE_API_MIN
PACKAGE_FORMULA_FILEPATH
PACKAGE_SUPPORT_BUILD_IN_PARALLEL
PACKAGE_DEVELOPER
EOF
}

# __info_the_given_available_package <PACKAGE-NAME> [--yaml] [--json] [<KEY>]
# __info_the_given_available_package curl
# __info_the_given_available_package curl version
# __info_the_given_available_package curl web-url
  __info_the_given_available_package() {
    case $2 in
        --yaml|'')
            __info_the_given_available_package_as_yaml "$1"
            ;;
        --json)
            __info_the_given_available_package_as_json "$1"
            ;;
        dofetch)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DOFETCH"
            ;;
        ltoable)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_LTOABLE"
            ;;
        movable)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_MOVABLE"
            ;;
        do12345)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DO12345"
            ;;
        dopatch)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DOPATCH"
            ;;
        prepare)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_PREPARE"
            ;;
        install)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DOBUILD"
            ;;
        dotweak)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DOTWEAK"
            ;;
        bindenv)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_BINDENV"
            ;;
        caveats)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_CAVEATS"
            ;;
        developer)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DEVELOPER"
            ;;
        src-ft)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_SRC_FILETYPE" ] ; then
                printf '%s\n' "$PACKAGE_SRC_FILETYPE"
            fi
            ;;
        src-fp)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_SRC_FILEPATH" ] ; then
                printf '%s\n' "$PACKAGE_SRC_FILEPATH"
            fi
            ;;
        fix-ft)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_FIX_FILETYPE" ] ; then
                printf '%s\n' "$PACKAGE_FIX_FILETYPE"
            fi
            ;;
        fix-fp)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_FIX_FILEPATH" ] ; then
                printf '%s\n' "$PACKAGE_FIX_FILEPATH"
            fi
            ;;
        res-ft)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_RES_FILETYPE" ] ; then
                printf '%s\n' "$PACKAGE_RES_FILETYPE"
            fi
            ;;
        res-fp)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_RES_FILEPATH" ] ; then
                printf '%s\n' "$PACKAGE_RES_FILEPATH"
            fi
            ;;
        *)  __load_formula_of_the_given_package "$1"
            __PACKAGE_GET__KEY__="$(printf '%s\n' "$2" | tr '+-.' '_' | tr a-z A-Z)"
            eval echo \$PACKAGE_$__PACKAGE_GET__KEY__
    esac
}

# __info_the_given_installed_package <PACKAGE-SPEC> [<KEY>]
# __info_the_given_installed_package curl
# __info_the_given_installed_package curl version
# __info_the_given_installed_package curl web-url
  __info_the_given_installed_package() {
    case $2 in
        --yaml|'')
            PACKAGE_SPEC=
            PACKAGE_SPEC="$(inspect_package_spec "$1")"

            if is_package_installed "$PACKAGE_SPEC" ; then
                yq "$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC/.ppkg/RECEIPT.yml"
            else
                abort 1 "package '$PACKAGE_SPEC' is not installed."
            fi
            ;;
        --json)
            __info_the_given_installed_package_as_json "$1"
            ;;
        --prefix)
            PACKAGE_SPEC=
            PACKAGE_SPEC="$(inspect_package_spec "$1")"

            if is_package_installed "$PACKAGE_SPEC" ; then
                PACKAGE_INSTALLED_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
                printf '%s\n' "$PACKAGE_INSTALLED_DIR"
            else
                abort 1 "package '$PACKAGE_SPEC' is not installed."
            fi
            ;;
        --files)
            PACKAGE_SPEC=
            PACKAGE_SPEC="$(inspect_package_spec "$1")"

            if is_package_installed "$PACKAGE_SPEC" ; then
                cat "$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC/.ppkg/MANIFEST.txt"
            else
                abort 1 "package '$PACKAGE_SPEC' is not installed."
            fi
            ;;
        builtat)
            __load_receipt_of_the_given_package "$1"
            printf '%s\n' "$RECEIPT_PACKAGE_BUILTAT"
            ;;
        builtat-rfc-3339)
            __load_receipt_of_the_given_package "$1"
            date -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%d %H:%M:%S%:z'
            ;;
        builtat-iso-8601)
            __load_receipt_of_the_given_package "$1"
            date -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%dT%H:%M:%S%:z'
            ;;
        builtat-rfc-3339-utc)
            __load_receipt_of_the_given_package "$1"
            date -u -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%d %H:%M:%S%:z'
            ;;
        builtat-iso-8601-utc)
            __load_receipt_of_the_given_package "$1"
            date -u -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%dT%H:%M:%SZ'
            ;;
        *)  __load_receipt_of_the_given_package "$1"
            __PACKAGE_GET__KEY__="$(printf '%s\n' "$2" | tr '+-.' '_' | tr a-z A-Z)"
            eval echo \$RECEIPT_PACKAGE_$__PACKAGE_GET__KEY__
    esac
}

# __info_the_given_installed_package_as_json <PACKAGE-NAME|PACKAGE_SPEC>
  __info_the_given_installed_package_as_json() {
    __load_receipt_of_the_given_package "$1"

    jq  --null-input \
        --arg pkgname "$RECEIPT_PACKAGE_PKGNAME" \
        --arg pkgtype "$RECEIPT_PACKAGE_PKGTYPE" \
        --arg version "$RECEIPT_PACKAGE_VERSION" \
        --arg summary "$RECEIPT_PACKAGE_SUMMARY" \
        --arg license "$RECEIPT_PACKAGE_LICENSE" \
        --arg web_url "$RECEIPT_PACKAGE_WEB_URL" \
        --arg git_url "$RECEIPT_PACKAGE_GIT_URL" \
        --arg git_sha "$RECEIPT_PACKAGE_GIT_SHA" \
        --arg git_ref "$RECEIPT_PACKAGE_GIT_REF" \
        --arg git_nth "$RECEIPT_PACKAGE_GIT_NTH" \
        --arg src_url "$RECEIPT_PACKAGE_SRC_URL" \
        --arg src_uri "$RECEIPT_PACKAGE_SRC_URI" \
        --arg src_sha "$RECEIPT_PACKAGE_SRC_SHA" \
        --arg fix_url "$RECEIPT_PACKAGE_FIX_URL" \
        --arg fix_uri "$RECEIPT_PACKAGE_FIX_URI" \
        --arg fix_sha "$RECEIPT_PACKAGE_FIX_SHA" \
        --arg res_url "$RECEIPT_PACKAGE_RES_URL" \
        --arg res_uri "$RECEIPT_PACKAGE_RES_URI" \
        --arg res_sha "$RECEIPT_PACKAGE_RES_SHA" \
        --arg patches "$RECEIPT_PACKAGE_PATCHES" \
        --arg reslist "$RECEIPT_PACKAGE_RESLIST" \
        --arg dep_pkg "$RECEIPT_PACKAGE_DEP_PKG" \
        --arg dep_res "$RECEIPT_PACKAGE_DEP_RES" \
        --arg dep_lib "$RECEIPT_PACKAGE_DEP_LIB" \
        --arg dep_upp "$RECEIPT_PACKAGE_DEP_UPP" \
        --arg dep_pym "$RECEIPT_PACKAGE_DEP_PYM" \
        --arg dep_plm "$RECEIPT_PACKAGE_DEP_PLM" \
        --arg dofetch "$RECEIPT_PACKAGE_DOFETCH" \
        --arg ltoable "$RECEIPT_PACKAGE_LTOABLE" \
        --arg movable "$RECEIPT_PACKAGE_MOVABLE" \
        --arg do12345 "$RECEIPT_PACKAGE_DO12345" \
        --arg dopatch "$RECEIPT_PACKAGE_DOPATCH" \
        --arg prepare "$RECEIPT_PACKAGE_PREPARE" \
        --arg install "$RECEIPT_PACKAGE_DOBUILD" \
        --arg dotweak "$RECEIPT_PACKAGE_DOTWEAK" \
        --arg bindenv "$RECEIPT_PACKAGE_BINDENV" \
        --arg caveats "$RECEIPT_PACKAGE_CAVEATS" \
        --arg bsystem "$RECEIPT_PACKAGE_BSYSTEM" \
        --arg binbstd "$RECEIPT_PACKAGE_BINBSTD" \
        --arg ccflags "$RECEIPT_PACKAGE_CCFLAGS" \
        --arg xxflags "$RECEIPT_PACKAGE_XXFLAGS" \
        --arg ppflags "$RECEIPT_PACKAGE_PPFLAGS" \
        --arg ldflags "$RECEIPT_PACKAGE_LDFLAGS" \
        --arg parallel $RECEIPT_PACKAGE_SUPPORT_BUILD_IN_PARALLEL \
        --arg developer "$RECEIPT_PACKAGE_DEVELOPER" \
        --arg builtby "$RECEIPT_PACKAGE_BUILTBY" \
        --arg builtat "$RECEIPT_PACKAGE_BUILTAT" \
        --arg builtfor "$RECEIPT_PACKAGE_BUILTFOR" \
'{
    "pkgname":$pkgname,
    "pkgtype":$pkgtype,
    "version":$version,
    "license":$license,
    "summary":$summary,
    "web-url":$web_url,
    "git-url":$git_url,
    "git-sha":$git_sha,
    "git-ref":$git_ref,
    "git-nth":$git_nth,
    "src-url":$src_url,
    "src-uri":$src_uri,
    "src-sha":$src_sha,
    "fix-url":$fix_url,
    "fix-uri":$fix_uri,
    "fix-sha":$fix_sha,
    "res-url":$res_url,
    "res-uri":$res_uri,
    "res-sha":$res_sha,
    "patches":$patches,
    "reslist":$reslist,
    "dep-pkg":$dep_pkg,
    "dep-res":$dep_res,
    "dep-lib":$dep_lib,
    "dep-upp":$dep_upp,
    "dep-pym":$dep_pym,
    "dep-plm":$dep_plm,
    "bsystem":$bsystem,
    "binbstd":$binbstd,
    "ccflags":$ccflags,
    "xxflags":$xxflags,
    "ppflags":$ppflags,
    "ldflags":$ldflags,
    "parallel":$parallel,
    "developer":$developer,
    "dofetch":$dofetch,
    "ltoable":$ltoable,
    "movable":$movable,
    "do12345":$do12345,
    "dopatch":$dopatch,
    "prepare":$prepare,
    "install":$install,
    "dotweak":$dotweak,
    "bindenv":$bindenv,
    "caveats":$caveats,
    "builtby":$builtby,
    "builtat":$builtat,
    "builtfor":$builtfor
}' | jq 'with_entries(select(.value != ""))'
}

# }}}
##############################################################################
# {{{ ppkg depends

# __show_packages_depended_by_the_given_package <PACKAGE-NAME> [-t <dot|d2|box|svg|png>] [-o <OUTPUT-PATH>]
__show_packages_depended_by_the_given_package() {
    [ -z "$1" ] && abort 1 "$PPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], <PACKAGE-NAME> is unspecified."

    PACKAGE_NAME="$1"

    shift

    ###########################################################################################

    unset OUTPUT_TYPE
    unset OUTPUT_PATH

    unset ENGINE

    while [ -n "$1" ]
    do
        case $1 in
            -t) shift
                case $1 in
                    dot|d2|box|svg|png)
                        OUTPUT_TYPE="$1" ;;
                    '') abort 1 "$PPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], -t option is given but <OUTPUT-TYPE> is unspecified." ;;
                    *)  abort 1 "$PPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>], unsupported <OUTPUT-TYPE>: $1, <OUTPUT-TYPE> should be one of dot|d2|box|svg|png"
                esac
                ;;
            -o) shift
                if [ -z "$1" ] ; then
                    abort 1 "$PPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], -o option is given but <OUTPUT-PATH> is unspecified."
                else
                    OUTPUT_PATH="$1"
                fi
                ;;
            --engine=*)
                ENGINE="${1#*=}"
                case $ENGINE in
                    d2|dot) ;;
                    *)  abort 1 "unrecognized diagram engine '$ENGINE', ppkg only support d2 and dot diagram engine."
                esac
                ;;
            *)  abort 1 "$PPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>] [-K], unrecognized option: $1"
        esac
        shift
    done

    ###########################################################################################

    unset OUTPUT_DIR
    unset OUTPUT_FILEPATH

    case $OUTPUT_PATH in
        '')
            if [ -z "$OUTPUT_TYPE" ] ; then
                OUTPUT_TYPE='box'
            fi
            ;;
        ..|../)
            if [ -z "$OUTPUT_TYPE" ] ; then
                OUTPUT_TYPE='box'
            fi

            OUTPUT_FILEPATH="$PWD/../$PACKAGE_NAME-dependencies.$OUTPUT_TYPE"
            ;;
        .|./)
            if [ -z "$OUTPUT_TYPE" ] ; then
                OUTPUT_TYPE='box'
            fi

            OUTPUT_FILEPATH="$PWD/$PACKAGE_NAME-dependencies.$OUTPUT_TYPE"
            ;;
        */)
            if [ -z "$OUTPUT_TYPE" ] ; then
                OUTPUT_TYPE='box'
            fi

            case $OUTPUT_PATH in
                /*) OUTPUT_DIR="$OUTPUT_PATH" ;;
                *)  OUTPUT_DIR="$PWD/$OUTPUT_PATH"
            esac

            OUTPUT_FILEPATH="$OUTPUT_DIR/$PACKAGE_NAME-dependencies.$OUTPUT_TYPE"
            ;;
        *)
            if [ -z "$OUTPUT_TYPE" ] ; then
                case $OUTPUT_PATH in
                    *.box) OUTPUT_TYPE='box' ;;
                    *.dot) OUTPUT_TYPE='dot' ;;
                    *.d2)  OUTPUT_TYPE='d2'  ;;
                    *.svg) OUTPUT_TYPE='svg' ;;
                    *.png) OUTPUT_TYPE='png' ;;
                    *)     OUTPUT_TYPE='box' ;;
                esac
            fi

            case $OUTPUT_PATH in
                /*) OUTPUT_DIR="${OUTPUT_PATH%/*}"
                    OUTPUT_FILEPATH="$OUTPUT_PATH"
                    ;;
                *)  OUTPUT_DIR="$PWD/$(dirname "$OUTPUT_PATH")"
                    OUTPUT_FILEPATH="$PWD/$OUTPUT_PATH"
            esac
    esac

    ###########################################################################################

    if [ -z "$ENGINE" ] ; then
        if [ "$OUTPUT_TYPE" = svg ] || [ "$OUTPUT_TYPE" = png ] ; then
            if command -v dot > /dev/null ; then
                ENGINE=dot
            elif command -v dot_static > /dev/null ; then
                ENGINE=dot_static
            elif command -v d2 > /dev/null ; then
                ENGINE=d2
            else
                abort 1 'none of dot, dot_static, d2 command was found. please install graphviz or d2 package, then try again.'
            fi
        fi
    else
        if [ "$ENGINE" = dot ] ; then
            ENGINE=dot_static
        fi
    fi

    ###########################################################################################

    unset GENERATE_D2

    if [ "$OUTPUT_TYPE" = d2 ] || [ "$ENGINE" = d2 ] ; then
        GENERATE_D2=1
    fi

    ###########################################################################################

    unset LINES

    unset HANDLED_PACKAGE_NAME_LIST

    unset STACK

    STACK="$PACKAGE_NAME"

    while [ -n "$STACK" ]
    do
        case $STACK in
            *\;*) PACKAGE_NAME="${STACK##*;}" ; STACK="${STACK%;*}" ;;
            *)    PACKAGE_NAME="${STACK}"     ; STACK=
        esac

        ################################################################

        HANDLED=0

        for HANDLED_PACKAGE_NAME in $HANDLED_PACKAGE_NAME_LIST
        do
            if [ "$HANDLED_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then
                HANDLED=1
                break
            fi
        done

        if [ "$HANDLED" = 1 ] ; then
            continue
        else
            HANDLED_PACKAGE_NAME_LIST="$HANDLED_PACKAGE_NAME_LIST $PACKAGE_NAME"
        fi

        #echo "HANDLED_PACKAGE_NAME_LIST=$HANDLED_PACKAGE_NAME_LIST"

        ################################################################

        __load_formula_of_the_given_package "$PACKAGE_NAME"

        ################################################################

        [ -z "$PACKAGE_DEP_PKG" ] && continue

        ################################################################

        if [ "$GENERATE_D2" = 1 ] ; then
            for item in $PACKAGE_DEP_PKG
            do
                LINES="$LINES
$PACKAGE_NAME -> $item"
            done
        else
            DOUBLE_QUOTE_LIST=

            for item in $PACKAGE_DEP_PKG
            do
                DOUBLE_QUOTE_LIST="$DOUBLE_QUOTE_LIST \"$item\""
            done

            LINES="$LINES
\"$PACKAGE_NAME\" -> {$DOUBLE_QUOTE_LIST }"
        fi

        ################################################################

        for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
        do
            if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then
                abort 1 "package '$PACKAGE_NAME' depends itself."
            fi

            if [ -z "$STACK" ] ; then
                STACK="$DEPENDENT_PACKAGE_NAME"
            else
                STACK="$STACK;$DEPENDENT_PACKAGE_NAME"
            fi
        done
    done

    ###########################################################################################

    [ -z "$LINES" ] && return 0

    ###########################################################################################

    case $OUTPUT_TYPE in
        dot)
            if [ -z "$OUTPUT_FILEPATH" ] ; then
                printf 'digraph G {\n%s\n}\n' "$LINES"
            else
                SESSION_DIR="$PPKG_HOME/run/$$"

                rm -rf     "$SESSION_DIR"
                install -d "$SESSION_DIR"
                cd         "$SESSION_DIR"

                printf 'digraph G {\n%s\n}\n' "$LINES" > dependencies.dot

                if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                    install -d "$OUTPUT_DIR"
                fi

                mv -T dependencies.dot "$OUTPUT_FILEPATH"

                rm -rf "$SESSION_DIR"
            fi
            ;;
        d2)
            if [ -z "$OUTPUT_FILEPATH" ] ; then
                printf '%s\n' "$LINES"
            else
                SESSION_DIR="$PPKG_HOME/run/$$"

                rm -rf     "$SESSION_DIR"
                install -d "$SESSION_DIR"
                cd         "$SESSION_DIR"

                printf '%s\n' "$LINES" > dependencies.d2

                if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                    install -d "$OUTPUT_DIR"
                fi

                mv -T dependencies.d2 "$OUTPUT_FILEPATH"

                rm -rf "$SESSION_DIR"
            fi
            ;;
        box)
            DOT_CONTENT="digraph G {
$LINES
}"

            if [ -z "$OUTPUT_FILEPATH" ] ; then
                # https://github.com/ggerganov/dot-to-ascii
                curl \
                    -s \
                    -G \
                    --data-urlencode "boxart=1" \
                    --data-urlencode "src=$DOT_CONTENT" \
                    'https://dot-to-ascii.ggerganov.com/dot-to-ascii.php'
            else
                SESSION_DIR="$PPKG_HOME/run/$$"

                rm -rf     "$SESSION_DIR"
                install -d "$SESSION_DIR"
                cd         "$SESSION_DIR"

                # https://github.com/ggerganov/dot-to-ascii
                curl \
                    -s \
                    -G \
                    -o dependencies.box \
                    --data-urlencode "boxart=1" \
                    --data-urlencode "src=$DOT_CONTENT" \
                    'https://dot-to-ascii.ggerganov.com/dot-to-ascii.php'

                if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                    install -d "$OUTPUT_DIR"
                fi

                mv dependencies.box "$OUTPUT_FILEPATH"

                rm -rf "$SESSION_DIR"
            fi
            ;;
        svg|png)
            if [ "$ENGINE" = d2 ] ; then
                if [ -z "$OUTPUT_FILEPATH" ] ; then
                    printf '%s\n' "$LINES" | d2 -
                else
                    if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                        install -d "$OUTPUT_DIR"
                    fi

                    printf '%s\n' "$LINES" | d2 - "$OUTPUT_FILEPATH"
                fi
            else
                SESSION_DIR="$PPKG_HOME/run/$$"

                rm -rf     "$SESSION_DIR"
                install -d "$SESSION_DIR"
                cd         "$SESSION_DIR"

                printf 'digraph G {\n%s\n}\n' "$LINES" > dependencies.dot

                if [ -z "$OUTPUT_FILEPATH" ] ; then
                    "$ENGINE" "-T$OUTPUT_TYPE" dependencies.dot
                else
                    "$ENGINE" "-T$OUTPUT_TYPE" -o dependencies.tmp dependencies.dot

                    if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                        install -d "$OUTPUT_DIR"
                    fi

                    mv -T dependencies.tmp "$OUTPUT_FILEPATH"
                fi

                rm -rf "$SESSION_DIR"
            fi
    esac
}

# }}}
##############################################################################
# {{{ ppkg fetch

__fetch_resources_of_the_given_package() {
    if [ -z "$1" ] ; then
        abort 1 "__fetch_resources_of_the_given_package <PACKAGE-NAME>, <PACKAGE-NAME> is unspecified."
    fi

    __load_formula_of_the_given_package "$1"

    if [ -n "$PACKAGE_SRC_URL" ] ; then
        case $PACKAGE_SRC_URL in
            dir://*)
                note "$PACKAGE_SRC_URL is local path, no need to fetch."
                return 0
                ;;
            file://*)
                note "$PACKAGE_SRC_URL is local path, no need to fetch."
                return 0
                ;;
            *)  wfetch "$PACKAGE_SRC_URL" --uri="$PACKAGE_SRC_URI" --sha256="$PACKAGE_SRC_SHA" -o "$PACKAGE_SRC_FILEPATH"
        esac
    elif [ -n "$PACKAGE_GIT_URL" ] ; then
        unset GIT_FETCH_URL

        if [ -z "$PPKG_URL_TRANSFORM" ] ; then
            GIT_FETCH_URL="$PACKAGE_GIT_URL"
        else
            GIT_FETCH_URL="$("$PPKG_URL_TRANSFORM" "$PACKAGE_GIT_URL")" || return 1
        fi

        if [ -z "$PACKAGE_GIT_SHA" ] ; then
            if [ -z "$PACKAGE_GIT_REF" ] ; then
                GIT_BRANCH_NAME=master
                GIT_REF_SPEC="+HEAD:refs/remotes/origin/master"
            else
                GIT_BRANCH_NAME="$(basename "$PACKAGE_GIT_REF")"
                GIT_REF_SPEC="+$PACKAGE_GIT_REF:refs/remotes/origin/$GIT_BRANCH_NAME"
            fi
        else
            GIT_BRANCH_NAME=master
            GIT_REF_SPEC="+$PACKAGE_GIT_SHA:refs/remotes/origin/master"
        fi

        if [ -z "$PACKAGE_GIT_NTH" ] ; then
            PACKAGE_GIT_NTH=1
        fi

        if [ "$PACKAGE_GIT_NTH" -eq 0 ] ; then
            if [ -f "$PACKAGE_SRC_FILEPATH/.git/shallow" ] ; then
                GIT_FETCH_EXTRA_OPTIONS='--unshallow'
            else
                GIT_FETCH_EXTRA_OPTIONS=
            fi
        else
            GIT_FETCH_EXTRA_OPTIONS="--depth=$PACKAGE_GIT_NTH"
        fi

        SESSION_DIR="$PPKG_HOME/run/$$"

        run rm -rf     "$SESSION_DIR"
        run install -d "$SESSION_DIR"
        run cd         "$SESSION_DIR"

        run git -c init.defaultBranch=master init
        run git remote add origin "$GIT_FETCH_URL"
        run git -c protocol.version=2 fetch --progress $GIT_FETCH_EXTRA_OPTIONS origin "$GIT_REF_SPEC"
        run git checkout --progress --force -B "$GIT_BRANCH_NAME" "refs/remotes/origin/$GIT_BRANCH_NAME"

        git_submodule_update_recursive

        rm -rf "$SESSION_DIR"
    fi

    if [ -n    "$PACKAGE_FIX_URL" ] ; then
        wfetch "$PACKAGE_FIX_URL" --uri="$PACKAGE_FIX_URI" --sha256="$PACKAGE_FIX_SHA" -o "$PACKAGE_FIX_FILEPATH"
    fi

    if [ -n    "$PACKAGE_RES_URL" ] ; then
        wfetch "$PACKAGE_RES_URL" --uri="$PACKAGE_RES_URI" --sha256="$PACKAGE_RES_SHA" -o "$PACKAGE_RES_FILEPATH"
    fi
}

# }}}
##############################################################################
# {{{ ppkg tree

# __tree_the_given_installed_package <PACKAGE-SPEC>
  __tree_the_given_installed_package() {
    PACKAGE_SPEC=
    PACKAGE_SPEC="$(inspect_package_spec "$1")"

    if is_package_installed "$PACKAGE_SPEC" ; then
        PACKAGE_INSTALLED_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
    else
        abort 1 "package '$PACKAGE_SPEC' is not installed."
    fi

    shift

    run tree "$@" "$PACKAGE_INSTALLED_DIR"
}

# }}}
##############################################################################
# {{{ ppkg logs

# __logs_the_given_installed_package <PACKAGE-SPEC>
  __logs_the_given_installed_package() {
    PACKAGE_SPEC=
    PACKAGE_SPEC="$(inspect_package_spec "$1")"

    if is_package_installed "$PACKAGE_SPEC" ; then
        PACKAGE_INSTALLED_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
    else
        abort 1 "package '$PACKAGE_SPEC' is not installed."
    fi

    cd "$PACKAGE_INSTALLED_DIR/.ppkg"

    if command -v bat > /dev/null ; then
        fzf --preview='bat --color=always --theme=Dracula {}' --preview-window='right:75%'
    else
        fzf
    fi
}

# }}}
##############################################################################
# {{{ ppkg bundle

__generate_wrapper_c_source_file() {
    cat > "$FILEPATH.c" <<EOF
#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <limits.h>

int main(int argc, char* argv[]) {
    char selfExePath[PATH_MAX];

    int n = readlink("/proc/self/exe", selfExePath, PATH_MAX);

    if (n == -1) {
        perror("/proc/self/exe");
        return 1;
    }

    selfExePath[n] = '\\0';

    ////////////////////////////////////////////////////

    const char * s = ".exe";

    int j;

    for (j = 0; s[j] != '\0'; j++);

    char realExePath[n + j + 1];

    int slashIndex = -1;

    int i;

    for (i = 0; i < n; i++) {
        realExePath[i] = selfExePath[i];

        if (selfExePath[i] == '/') {
            slashIndex = i;
        }
    }

    char * p = realExePath + n;

    for (i = 0; i <= j; i++) {
        p[i] = s[i];
    }
EOF

    ####################################

    [ -n "$RECEIPT_PACKAGE_BINDENV" ] && {
        I=0

        for LINE in $RECEIPT_PACKAGE_BINDENV
        do
            VALUE="${LINE#*=}"

            case $VALUE in
                %s/*)
                    I="$(($I + 1))"
                    KEY="${LINE%%=*}"
                    VALUE="$(printf "$VALUE\n" 'bundle.d')"
                    VALUE_RELATIVE_TO_SELF_EXE_PATH="$(realpath -m --relative-to="${FILEPATH%/*}" "$VALUE")"

                    cat >> "$FILEPATH.c" <<EOF

    ////////////////////////////////////////////////////

    p = getenv("$KEY");

    if (p == NULL || p[0] == '\0') {
        s = "$VALUE_RELATIVE_TO_SELF_EXE_PATH";

        for (j = 0; s[j] != '\0'; j++);

        char pathBuf[slashIndex + j + 1];

        for (i = 0; i <= slashIndex; i++) {
            pathBuf[i] = selfExePath[i];
        }

        p = pathBuf + slashIndex + 1;

        for (i = 0U; i <= j; i++) {
            p[i] = s[i];
        }

        if (setenv("$KEY", pathBuf, 1) != 0) {
            perror("$KEY");
            return 10;
        }
    }
EOF
                    ;;
                *)  cat >> "$FILEPATH.c" <<EOF

    ////////////////////////////////////////////////////

    if (putenv("$LINE") != 0) {
        perror(NULL);
        return 10;
    }
EOF
            esac

        done
    }

    ####################################

    if [ -z "$DYNAMIC_LOADER_FILENAME" ] ; then
        cat >> "$FILEPATH.c" <<EOF

    ////////////////////////////////////////////////////

    argv[0] = realExePath;

    execv (realExePath, argv);
    perror(realExePath);
    return 255;
}
EOF
    else
        cat >> "$FILEPATH.c" <<EOF

    ////////////////////////////////////////////////////

    const char * const dynamicLoaderName = "$DYNAMIC_LOADER_FILENAME";
    const char * const libraryPathRelativeToSelfExePath = "$LIBRARY_PATH_RELATIVE_TO_SELF_EXE_PATH";

    ////////////////////////////////////////////////////

    for (j = 0; libraryPathRelativeToSelfExePath[j] != '\0'; j++);

    char libraryPath[slashIndex + j + 1];

    for (i = 0; i <= slashIndex; i++) {
        libraryPath[i] = selfExePath[i];
    }

    p = libraryPath + slashIndex + 1;

    for (i = 0; i <= j; i++) {
        p[i] = libraryPathRelativeToSelfExePath[i];
    }

    ////////////////////////////////////////////////////

    int k;

    for (k = 0; dynamicLoaderName[k] != '\0'; k++);

    char dynamicLoaderPath[slashIndex + j + k + 2];

    for (i = 0; i <= slashIndex; i++) {
        dynamicLoaderPath[i] = selfExePath[i];
    }

    p = dynamicLoaderPath + slashIndex + 1;

    for (i = 0; i < j; i++) {
        p[i] = libraryPathRelativeToSelfExePath[i];
    }

    p += j;

    p[0] = '/';

    p++;

    for (i = 0; i <= k; i++) {
        p[i] = dynamicLoaderName[i];
    }

    ////////////////////////////////////////////////////

    char* args[argc + 6];

    args[0] = dynamicLoaderPath;
    args[1] = (char*)"--library-path";
    args[2] = libraryPath;
    args[3] = (char*)"--argv0";
    args[4] = selfExePath;
    args[5] = realExePath;

    n = 6;

    for (i = 1; i < argc; i++) {
        args[n++] = argv[i];
    }

    args[n] = NULL;

    execv (dynamicLoaderPath, args);
    perror(dynamicLoaderPath);
    return 255;
}
EOF
    fi
}

# __bundle_the_given_installed_package <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>] [--exclude <EXCLUDE-PATH>] [-K] [--portable]
  __bundle_the_given_installed_package() {
    __load_receipt_of_the_given_package "$1"

    #######################################################

    unset OUTPUT_DIR
    unset OUTPUT_PATH
    unset OUTPUT_TYPE
    unset OUTPUT_NAME

    case $2 in
        '') abort 1 "$PPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>], forth argument is unspecified."
            ;;
        */*)
            OUTPUT_DIR="${2%/*}"
            [ -z "$OUTPUT_DIR" ] && OUTPUT_DIR=/
            OUTPUT_NAME="${2##*/}"
            ;;
        *)  OUTPUT_NAME="$2"
    esac

    case $OUTPUT_NAME in
        '') abort 1 "$PPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>, <BUNDLE-TYPE> is unspecified."
            ;;
        *.tar.gz)
            OUTPUT_TYPE=.tar.gz
            ;;
        *.tar.xz)
            OUTPUT_TYPE=.tar.xz
            ;;
        *.tar.lz)
            OUTPUT_TYPE=.tar.lz
            ;;
        *.tar.bz2)
            OUTPUT_TYPE=.tar.bz2
            ;;
        *.zip)
            OUTPUT_TYPE=.zip
            ;;
        *.AppImage)
            OUTPUT_TYPE=.AppImage
            ;;
        *)  abort 1 "$PPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>, invalid forth argument: $2"
    esac

    if [ "$OUTPUT_NAME" = "$OUTPUT_TYPE" ] ; then
        if [ -z "$OUTPUT_DIR"  ] ; then
            OUTPUT_PATH=.
        else
            OUTPUT_PATH="$OUTPUT_DIR/"
        fi
    else
        OUTPUT_PATH="$2"
    fi

    #######################################################

    shift 2

    unset REQUEST_TO_KEEP_SESSION_DIR

    unset EXCLUDES

    unset PORTABLE

    unset SIGN_WITH_GPG

    unset SIGNKEY

    while [ -n "$1" ]
    do
        case $1 in
            -K) REQUEST_TO_KEEP_SESSION_DIR=1
                ;;
            --exclude)
                shift
                if [ -z "$1" ] ; then
                    abort 1 "$PPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>] [--exclude <PATH>], --exclude option is specified but <PATH> is unspecified."
                else
                    EXCLUDES="$EXCLUDES $1"
                fi
                ;;
            --portable)
                PORTABLE=1
                ;;
            --sign)
                SIGN_WITH_GPG=1
                ;;
            --sign-key=*)
                SIGNKEY="${1#*=}"
                ;;
            --) break ;;
            *)  abort 1 "$PPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>] [--portable], unrecognized option: $1"
        esac
        shift
    done

    #######################################################

    OLDCWD="$PWD"

    SESSION_DIR="$PPKG_HOME/run/$$"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    #######################################################

    if [ -n "$EXCLUDES" ] || { [ "$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME" = linux ] && [ "$PORTABLE" = 1 ]
                             } || [ "$OUTPUT_TYPE" = .AppImage ] ; then
        run install -d bundle.d/

        run cp -r "$PACKAGE_INSTALLED_DIR/." bundle.d/

        for EXCLUDE in $EXCLUDES
        do
            run rm -rf "bundle.d/$EXCLUDE"
        done
    else
        run ln -s "$PACKAGE_INSTALLED_DIR" bundle.d
    fi

    #######################################################

    if [ "$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME" = linux ] ; then
        find bundle.d/ -type f -not -path 'bundle.d/.ppkg/*' > fs.txt

        unset OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME

        if [ "$PORTABLE" = 1 ] ; then
            unset DYNAMIC_LOADER_FILEPATH
            unset DYNAMIC_LOADER_FILENAME

            while read -r FILEPATH
            do
                FILEMAGIC="$("$PPKG_CORE_DIR/file-magic" "$FILEPATH")"

                case $FILEMAGIC in
                    7F454C460100)
                        # object file
                        OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1
                        continue
                        ;;
                    7F454C460200)
                        DYNAMIC_LOADER_FILEPATH="$("$PPKG_CORE_DIR/print-interpreter" "$FILEPATH")"

                        # fully statically linked executable
                        if [ -z "$DYNAMIC_LOADER_FILEPATH" ] ; then
                            if [ -f "$FILEPATH.c" ] ; then
                                run mv "$FILEPATH" "$FILEPATH.exe"
                                run cc -static -std=gnu11 -Os -s -flto $CPPFLAGS -o "$FILEPATH" "$FILEPATH.c"
                            else
                                [ -z "$RECEIPT_PACKAGE_BINDENV" ] && continue
                                DYNAMIC_LOADER_FILENAME=
                                __generate_wrapper_c_source_file
                                run mv "$FILEPATH" "$FILEPATH.exe"
                                run cc -static -std=gnu11 -Os -s -flto $CPPFLAGS -o "$FILEPATH" "$FILEPATH.c"
                            fi
                        else
                            DYNAMIC_LOADER_FILENAME="${DYNAMIC_LOADER_FILEPATH##*/}"

                            LIBRARY_PATH_RELATIVE_TO_SELF_EXE_PATH="$(realpath -m --relative-to="${FILEPATH%/*}" bundle.d/.ppkg/dependencies/lib)"

                            if [ -f "$FILEPATH.c" ] ; then
                                CPPFLAGS="-DDYNAMIC_LOADER_FILENAME=\"\\\"$DYNAMIC_LOADER_FILENAME\\\"\" -DLIBRARY_PATH_RELATIVE_TO_SELF_EXE_PATH=\"\\\"$LIBRARY_PATH_RELATIVE_TO_SELF_EXE_PATH\\\"\""
                            else
                                CPPFLAGS=
                                __generate_wrapper_c_source_file
                            fi

                            run mv "$FILEPATH" "$FILEPATH.exe"

                            run cc -static -std=gnu11 -Os -s -flto $CPPFLAGS -o "$FILEPATH" "$FILEPATH.c"
                        fi
                        ;;
                    7F454C460300)
                        DYNAMIC_LOADER_FILEPATH="$("$PPKG_CORE_DIR/print-interpreter" "$FILEPATH")"

                        # shared library
                        if [ -z "$DYNAMIC_LOADER_FILEPATH" ] ; then
                            # TODO should check if this shared library is needed by executables
                            if [ -z "$RECEIPT_PACKAGE_BINDENV" ] ; then
                                OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1
                            fi
                            continue
                        fi

                        DYNAMIC_LOADER_FILENAME="${DYNAMIC_LOADER_FILEPATH##*/}"

                        LIBRARY_PATH_RELATIVE_TO_SELF_EXE_PATH="$(realpath -m --relative-to="${FILEPATH%/*}" bundle.d/.ppkg/dependencies/lib)"

                        if [ -f "$FILEPATH.c" ] ; then
                            CPPFLAGS="-DDYNAMIC_LOADER_FILENAME=\"\\\"$DYNAMIC_LOADER_FILENAME\\\"\" -DLIBRARY_PATH_RELATIVE_TO_SELF_EXE_PATH=\"\\\"$LIBRARY_PATH_RELATIVE_TO_SELF_EXE_PATH\\\"\""
                        else
                            CPPFLAGS=
                            __generate_wrapper_c_source_file
                        fi

                        run mv "$FILEPATH" "$FILEPATH.exe"

                        run cc -static -std=gnu11 -Os -s -flto $CPPFLAGS -o "$FILEPATH" "$FILEPATH.c"
                        ;;
                    213C61726368)
                        # static library file
                        OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1
                        ;;
                esac
            done < fs.txt

            if [ -n "$DYNAMIC_LOADER_FILENAME" ] ; then
                install -d bundle.d/.ppkg/dependencies/lib/

                NEEDED_SYSTEM_DYLIBS="$(ls bundle.d/.ppkg/dependencies/sys/)"

                for NEEDED_FILENAME in $DYNAMIC_LOADER_FILENAME $NEEDED_SYSTEM_DYLIBS
                do
                    [ -f "bundle.d/.ppkg/dependencies/lib/$NEEDED_FILENAME" ] && continue

                    NEEDED_FILEPATH="$(gcc -print-file-name="$NEEDED_FILENAME")"

                    case $NEEDED_FILEPATH in
                        /*) run cp -L "$NEEDED_FILEPATH" bundle.d/.ppkg/dependencies/lib/ ;;
                        *)  abort 1 "required system library '$NEEDED_FILENAME' could not be found."
                    esac
                done
            fi
        else
            while read -r FILEPATH
            do
                FILEMAGIC="$("$PPKG_CORE_DIR/file-magic" "$FILEPATH")"

                case $FILEMAGIC in
                    7F454C460[13]00)
                        # object file
                        # dynamically linked library or executable
                        OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1
                        break
                        ;;
                    213C61726368)
                        # static library file
                        OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1
                        break
                        ;;
                esac
            done < fs.txt
        fi

        if [ "$OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME" = 1 ] ; then
            BUNDLE_DIR_NAME="${RECEIPT_PACKAGE_PKGNAME%@*}-$RECEIPT_PACKAGE_VERSION-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM"
        else
            BUNDLE_DIR_NAME="${RECEIPT_PACKAGE_PKGNAME%@*}-$RECEIPT_PACKAGE_VERSION-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH"
        fi
    else
        BUNDLE_DIR_NAME="${RECEIPT_PACKAGE_PKGNAME%@*}-$RECEIPT_PACKAGE_VERSION-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM"
    fi

    BUNDLE_DIR_NAME="$BUNDLE_DIR_NAME.$RECEIPT_PACKAGE_PROFILE"

    OUTPUT_FILENAME="$BUNDLE_DIR_NAME$OUTPUT_TYPE"

    #######################################################

    if [ "$OUTPUT_TYPE" = .AppImage ] ; then
        run "$UPPM" about
        run "$UPPM" update

        for UPPM_PACKAGE_NAME in curl zsync gnupg bsdtar sysinfo xmlutils coreutils findutils squashfs appstream desktop-file-utils
        do
            run "$UPPM" install "$UPPM_PACKAGE_NAME" "$UPPM_INSTALL_ARGS"

            UPPM_PACKAGE_INSTALLED_DIR="$UPPM_HOME/installed/$UPPM_PACKAGE_NAME"

            if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/bin" ] ; then
                PATH="$UPPM_PACKAGE_INSTALLED_DIR/bin:$PATH"
            fi

            if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/sbin" ] ; then
                PATH="$UPPM_PACKAGE_INSTALLED_DIR/sbin:$PATH"
            fi
        done

        #############################################################

        unset APPEXEC_FILEPATH
        unset APPICON_FILEPATH
        unset APPDATA_FILEPATH
        unset DESKTOP_FILEPATH

        unset DESKTOP_FILENAME
        unset APPICON_FILENAME

        unset APPID
        unset APPEXEC

        #############################################################

        run cd bundle.d

        #############################################################

        if [ "$CHECK_APPSTREAM" = 1 ] ; then
            run appstreamcli validate-tree .
        fi

        #############################################################

        [ -d share/metainfo ] && {
            for item in metainfo appdata
            do
                APPDATA_FILEPATH="$(find -L share/metainfo -type f -name "*.$item.xml" -printf '%p\n' -quit)"

                [ -n "$APPDATA_FILEPATH" ] && break
            done
        }

        [ -z "$APPDATA_FILEPATH" ] && {
            for item in metainfo appdata
            do
                APPDATA_FILEPATH="$(find -L -type f -name "*.$item.xml" -not -path './.ppkg/*' -printf '%P\n' -quit)"

                [ -n "$APPDATA_FILEPATH" ] && break
            done
        }

        [ -n "$APPDATA_FILEPATH" ] && {
              APPID="$(xmllint --xpath 'string(/component/id)'      "$APPDATA_FILEPATH")"
            APPNAME="$(xmllint --xpath 'string(/component/name)'    "$APPDATA_FILEPATH")"
            SUMMARY="$(xmllint --xpath 'string(/component/summary)' "$APPDATA_FILEPATH")"
            APPEXEC="$(xmllint --xpath 'string(/component/provides/binary)' "$APPDATA_FILEPATH")"

            [ -z "$APPID" ] && abort 1 "id tag is missing in file: $APPDATA_FILEPATH, for more details, please refer to https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#spec-component-filespec"
            [ -z "$APPNAME" ] && abort 1 "name tag is missing in file: $APPDATA_FILEPATH, for more details, please refer to https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#spec-component-filespec"
            [ -z "$SUMMARY" ] && abort 1 "summary tag is missing in file: $APPDATA_FILEPATH, for more details, please refer to https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#spec-component-filespec"

            case $APPID in
                *.desktop)  DESKTOP_FILENAME="$APPID" ;;
                *)          DESKTOP_FILENAME="$APPID.desktop"
            esac
        }

        #############################################################

        if [ -z "$APPEXEC" ] ; then
            APPEXEC="${RECEIPT_PACKAGE_PKGNAME%@*}"
        fi

        for dir in bin sbin
        do
            if [ -f "$dir/$APPEXEC" ] ; then
                APPEXEC_FILEPATH="$dir/$APPEXEC"
                break
            fi
        done

        if [ -z "$APPEXEC_FILEPATH" ] ; then
            APPEXEC_FILEPATH="$(find -L -type f -name "$APPEXEC" -printf '%P\n' -quit)"
        fi

        #############################################################

        unset EXPOSED_EXECUTABLES

        for d in bin sbin
        do
            [ -d "$d" ] || continue

            for f in $(ls "$d")
            do
                FILEPATH="$d/$f"

                [ -x "$FILEPATH" ] || continue

                FILEMAGIC="$("$PPKG_CORE_DIR/file-magic" "$FILEPATH")"

                printf '%s : %s\n' "$FILEMAGIC" "$FILEPATH"

                case $FILEMAGIC in
                    2321*)
                        # script
                        EXPOSED_EXECUTABLES="$EXPOSED_EXECUTABLES $FILEPATH"
                        ;;
                    7F454C460200)
                        # executable
                        EXPOSED_EXECUTABLES="$EXPOSED_EXECUTABLES $FILEPATH"
                        ;;
                    7F454C460300)
                        # dynamically linked library or executable
                        EXPOSED_EXECUTABLES="$EXPOSED_EXECUTABLES $FILEPATH"
                        ;;
                esac
            done
        done

        if [ -z "$EXPOSED_EXECUTABLES" ] ; then
            abort 1 "no executables in package: $PACKAGE_SPEC"
        fi

        EXPOSED_EXECUTABLES="${EXPOSED_EXECUTABLES# }"

        if [ "$(list_size $EXPOSED_EXECUTABLES)" = 1 ] ; then
            APPEXEC_FILEPATH="$EXPOSED_EXECUTABLES"

            # AppRun is required for appimage-runtime
            run ln -s "$APPEXEC_FILEPATH" AppRun
        else
            if [ -z "$APPEXEC_FILEPATH" ] ; then
                APPEXEC_FILEPATH="${EXPOSED_EXECUTABLES%% *}"
            fi

            cat > AppRun.c <<EOF
#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>

#include <sys/stat.h>

#if defined (__linux__)
#include <linux/limits.h>
#else
#include <limits.h>
#endif

int main(int argc, char* argv[]) {
    // https://docs.appimage.org/packaging-guide/environment-variables.html#type-2-appimage-runtime
    const char * const APPDIR = getenv("APPDIR");

    if (APPDIR == NULL || APPDIR[0] == '\0') {
        fprintf(stderr, "APPDIR environment variable is not set.\n");
        return 1;
    }

    ////////////////////////////////////////////////////

    const char * const ARGV0 = getenv("ARGV0");

    if (ARGV0 == NULL || ARGV0[0] == '\0') {
        fprintf(stderr, "ARGV0 environment variable is not set.\n");
        return 2;
    }

    ////////////////////////////////////////////////////

    const char * cmdName = NULL;

    ////////////////////////////////////////////////////

    int slashIndex = -1;

    for (int i = 0; ; i++) {
        if (ARGV0[i] == '\0') {
            break;
        }

        if (ARGV0[i] == '/') {
            slashIndex = i;
        }
    }

    if (slashIndex == -1) {
        cmdName = ARGV0;
    } else {
        cmdName = &ARGV0[slashIndex + 1];
    }

    ////////////////////////////////////////////////////

    char cmdPATH[PATH_MAX];

    int APPDIRLength = 0;

    for (int i = 0; ;i++) {
        if (APPDIR[i] == '\0') {
            APPDIRLength = i;
            cmdPATH[i] = '/';
            break;
        } else {
            cmdPATH[i] = APPDIR[i];
        }
    }

    ////////////////////////////////////////////////////

    cmdPATH[APPDIRLength + 1] = 'b';
    cmdPATH[APPDIRLength + 2] = 'i';
    cmdPATH[APPDIRLength + 3] = 'n';
    cmdPATH[APPDIRLength + 4] = '/';

    char * p = &cmdPATH[APPDIRLength + 5];

    for (int i = 0; ;i++) {
        p[i] = cmdName[i];

        if (cmdName[i] == '\0') {
            break;
        }
    }

    struct stat st;

    if (stat(cmdPATH, &st) == 0 && S_ISREG(st.st_mode)) {

    } else {
        cmdPATH[APPDIRLength + 1] = 's';
        cmdPATH[APPDIRLength + 2] = 'b';
        cmdPATH[APPDIRLength + 3] = 'i';
        cmdPATH[APPDIRLength + 4] = 'n';
        cmdPATH[APPDIRLength + 5] = '/';

        p = &cmdPATH[APPDIRLength + 6];

        for (int i = 0; ;i++) {
            p[i] = cmdName[i];

            if (cmdName[i] == '\0') {
                break;
            }
        }

        if (stat(cmdPATH, &st) == 0 && S_ISREG(st.st_mode)) {

        } else {
            const char * const defaultEXE = "$APPEXEC_FILEPATH";

            p = &cmdPATH[APPDIRLength + 1];

            for (int i = 0; ;i++) {
                p[i] = defaultEXE[i];

                if (defaultEXE[i] == '\0') {
                    break;
                }
            }
        }
    }

    ////////////////////////////////////////////////////

    argv[0] = cmdPATH;
    execv (cmdPATH, argv);
    perror(cmdPATH);
    return 255;
}
EOF
            run gcc -static -std=gnu11 -Os -s -flto -o AppRun AppRun.c
        fi

        #############################################################

        for d in share/icons/hicolor/256x256/apps share/icons/hicolor/128x128/apps
        do
            [ -d "$d" ] || continue

            for type in svg png
            do
                APPICON_FILEPATH="$(find -L "$d" -type f -name "*.$type" -printf '%p\n' -quit)"

                [ -n "$APPICON_FILEPATH" ] && break 2
            done
        done

        [ -z "$APPICON_FILEPATH" ] && {
            for type in svg png
            do
                APPICON_FILEPATH="$(find -L -type f -name "*.$type" -not -path './.ppkg/*' -printf '%P\n' -quit)"

                [ -n "$APPICON_FILEPATH" ] && break
            done
        }

        [ -n "$APPICON_FILEPATH" ] && {
            APPICON_FILENAME="${APPICON_FILEPATH##*/}"

            run ln -s "$APPICON_FILEPATH" "$APPICON_FILENAME"

            # https://docs.appimage.org/reference/appdir.html
            # .DirIcon is required for some softwares e.g. https://github.com/TheAssassin/AppImageLauncher to display thumbnail
            ln -s "$APPICON_FILEPATH" .DirIcon
        }

        #############################################################

        # appimage-runtime do not care of .desktop file, but other tools might take care of it

        for d in share/applications .
        do
            [ -d "$d" ] || continue

            for item in $DESKTOP_FILENAME '*.desktop'
            do
                DESKTOP_FILEPATH="$(find -L "$d" -type f -name "$item" -printf '%p\n' -quit)"

                if [ -n "$DESKTOP_FILEPATH" ] ; then
                    DESKTOP_FILENAME="${DESKTOP_FILEPATH##*/}"
                    run ln -s "$DESKTOP_FILEPATH" "$DESKTOP_FILENAME"
                    break 2
                fi
            done
        done

        if [ -n "$DESKTOP_FILENAME" ] ; then
            run desktop-file-validate "$DESKTOP_FILENAME"
        fi

        #############################################################

        tee app.yml <<EOF
name: $RECEIPT_PACKAGE_PKGNAME
arch: $RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH
version: $RECEIPT_PACKAGE_VERSION
homeurl: $RECEIPT_PACKAGE_WEB_URL
summary: $RECEIPT_PACKAGE_SUMMARY
license: $RECEIPT_PACKAGE_LICENSE
mainexe: $APPEXEC_FILEPATH
appicon: $APPICON_FILEPATH
desktop: $DESKTOP_FILEPATH
appdata: $APPDATA_FILEPATH
creator: ppkg|$PPKG_VERSION|https://github.com/leleliu008/ppkg
EOF

        ############################################################################

        run cd -

        ############################################################################

        case $RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH in
            x86_64|aarch64)
                wfetch "https://github.com/AppImage/type2-runtime/releases/download/continuous/runtime-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH" -o runtime --no-buffer
                ;;
            *)  wfetch "https://github.com/leleliu008/appimage-runtime-type2-prebuild/releases/download/2025.06.18-5e7217b7cfeecee1491c2d251e355c3cf8ba6e4d/appimage-runtime-type2-2025.06.18-linux-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH.release.tar.xz" -o runtime.tar.xz --no-buffer
                run bsdtar xf runtime.tar.xz --strip-components=1 --no-same-owner
                run mv bin/appimage-runtime-type2 runtime
        esac

        ############################################################################

        if [ -z "$@" ] ; then
            run mksquashfs bundle.d squashfs -comp zstd -b 128K -root-owned -noappend
        else
            run mksquashfs bundle.d squashfs "$@"
        fi

        ############################################################################

        run 'cat runtime squashfs > AppImage'

        run chmod a+x AppImage

        ############################################################################

        if [ "$SIGN_WITH_GPG" = 1 ] ; then
            if [ -z "$SIGNKEY" ] ; then
                SIGN_ARGS=
            else
                SIGN_ARGS="--sign-key $SIGNKEY"
            fi

            run gpg --sign --output AppImage.sig AppImage $SIGN_ARGS
        fi

        ############################################################################

        run mv AppImage "$OUTPUT_FILENAME"

        if [ "$SIGN_WITH_GPG" = 1 ] ; then
            run mv AppImage.sig "$OUTPUT_FILENAME.sig"
        fi

        ############################################################################

        if [ -n "$GITHUB_REPOSITORY" ] ; then
            URL="https://github.com/$GITHUB_REPOSITORY/releases/download/"

            run zsyncmake -u "$URL" "$OUTPUT_FILENAME"
        fi
    else
        run mv bundle.d "$BUNDLE_DIR_NAME"

        run bsdtar cvaf "$OUTPUT_FILENAME" "$BUNDLE_DIR_NAME/*" "$BUNDLE_DIR_NAME/.ppkg"
    fi

    run du -sh "$OUTPUT_FILENAME"

    run cd "$OLDCWD"

    if [ -n "$OUTPUT_DIR" ] && [ "$OUTPUT_DIR" != . ] && [ "$OUTPUT_DIR" != .. ] && [ "$OUTPUT_DIR" != / ] && [ ! -d "$OUTPUT_DIR" ] ; then
        run install -d "$OUTPUT_DIR"
    fi

    run mv "$SESSION_DIR/$OUTPUT_FILENAME" "$OUTPUT_PATH"

    #######################################################

    if [ "$REQUEST_TO_KEEP_SESSION_DIR" = 1 ] ; then
        echo
        note "the session directory '$SESSION_DIR' is not deleted as -K option is specified."
    else
        run rm -rf "$SESSION_DIR"
    fi
}

# }}}
##############################################################################
# {{{ ppkg export

# __export_the_given_installed_package <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<EXPORT-TYPE> [--exclude <EXCLUDE-PATH>] [-K]
  __export_the_given_installed_package() {
    __load_receipt_of_the_given_package "$1"

    #######################################################

    unset OUTPUT_DIR
    unset OUTPUT_PATH
    unset OUTPUT_TYPE
    unset OUTPUT_NAME

    case $2 in
        '') abort 1 "$PPKG_ARG0 export <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>], forth argument is unspecified."
            ;;
        */*)
            OUTPUT_DIR="${2%/*}"
            [ -z "$OUTPUT_DIR" ] && OUTPUT_DIR=/
            OUTPUT_NAME="${2##*/}"
            ;;
        *)  OUTPUT_NAME="$2"
    esac

    case $OUTPUT_NAME in
        '') abort 1 "$PPKG_ARG0 export <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<EXPORT-TYPE>, <BUNDLE-TYPE> is unspecified."
            ;;
        *.deb)
            OUTPUT_TYPE=.deb
            ;;
        *.rpm)
            OUTPUT_TYPE=.rpm
            ;;
        *.apk)
            OUTPUT_TYPE=.apk
            ;;
        *.pkg.tar.xz)
            OUTPUT_TYPE=.pkg.tar.xz
            ;;
        *)  abort 1 "$PPKG_ARG0 export <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<EXPORT-TYPE>, invalid forth argument: $2"
    esac

    if [ "$OUTPUT_NAME" = "$OUTPUT_TYPE" ] ; then
        if [ -z "$OUTPUT_DIR"  ] ; then
            OUTPUT_PATH=.
        else
            OUTPUT_PATH="$OUTPUT_DIR/"
        fi
    else
        OUTPUT_PATH="$2"
    fi

    #######################################################

    shift 2

    unset REQUEST_TO_KEEP_SESSION_DIR

    unset EXCLUDES

    while [ -n "$1" ]
    do
        case $1 in
            -K)
                REQUEST_TO_KEEP_SESSION_DIR=1
                ;;
            --exclude)
                shift
                if [ -z "$1" ] ; then
                    abort 1 "$PPKG_ARG0 export <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<EXPORT-TYPE>] [--exclude <PATH>], --exclude option is specified but <PATH> is unspecified."
                else
                    EXCLUDES="$EXCLUDES $1"
                fi
                ;;
            *)  abort 1 "$PPKG_ARG0 export <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<EXPORT-TYPE>] [--portable], unrecognized option: $1"
        esac
        shift
    done

    #######################################################

    OLDCWD="$PWD"

    SESSION_DIR="$PPKG_HOME/run/$$"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    #######################################################

    if [ "$OUTPUT_TYPE" = .pkg.tar.xz ] ; then
        OUTPUT_KIND=pkg
    else
        OUTPUT_KIND="${OUTPUT_TYPE#.}"
    fi

    __export_the_given_installed_package_as_$OUTPUT_KIND

    #######################################################

    run du -sh *$OUTPUT_TYPE

    #######################################################

    run cd "$OLDCWD"

    if [ -n "$OUTPUT_DIR" ] && [ "$OUTPUT_DIR" != . ] && [ "$OUTPUT_DIR" != .. ] && [ "$OUTPUT_DIR" != / ] && [ ! -d "$OUTPUT_DIR" ] ; then
        run install -d "$OUTPUT_DIR"
    fi

    run mv "$SESSION_DIR/*$OUTPUT_TYPE" "$OUTPUT_PATH"

    #######################################################

    if [ "$REQUEST_TO_KEEP_SESSION_DIR" = 1 ] ; then
        echo
        note "the session directory '$SESSION_DIR' is not deleted as -K option is specified."
    else
        run rm -rf "$SESSION_DIR"
    fi
}

__export_the_given_installed_package_as_deb() {
    run install -d ROOT/DEBIAN/
    run install -d ROOT/usr/local/

    run cp -r -L "$PACKAGE_INSTALLED_DIR"/* ROOT/usr/local/

    SIZE="$(du -sk ROOT | cut -f1)"

    case $RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH in
        x86_64) ARCHITECTURE='amd64' ;;
        x86)    ARCHITECTURE='i386'  ;;
        *)      ARCHITECTURE="$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH"
    esac

    case $RECEIPT_PACKAGE_GIT_URL in
        https://github.com/*)
            ISSUE_TRACKER_URL="$RECEIPT_PACKAGE_GIT_URL/issues" ;;
        *)  ISSUE_TRACKER_URL="$RECEIPT_PACKAGE_WEB_URL"
    esac

    # https://manpages.debian.org/buster/dpkg-dev/deb-control.5.en.html
    run tee ROOT/DEBIAN/control <<EOF
Package: $RECEIPT_PACKAGE_PKGNAME
Version: $RECEIPT_PACKAGE_VERSION
Section: custom
Priority: optional
Essential: no
Bugs: $ISSUE_TRACKER_URL
Homepage: $RECEIPT_PACKAGE_WEB_URL
Maintainer: $RECEIPT_PACKAGE_WEB_URL
Description: $RECEIPT_PACKAGE_SUMMARY
Architecture: $ARCHITECTURE
Installed-Size: $SIZE
EOF

    # https://manpages.debian.org/buster/dpkg/dpkg-deb.1.en.html
    run dpkg-deb --root-owner-group --build ROOT pkg.deb
    run dpkg-deb --contents pkg.deb
    run dpkg-deb --show pkg.deb
    run dpkg-deb --info pkg.deb

    run mv pkg.deb "$RECEIPT_PACKAGE_PKGNAME-$RECEIPT_PACKAGE_VERSION-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH.deb"
}

__export_the_given_installed_package_as_rpm() {
    # https://www.redhat.com/sysadmin/create-rpm-package
    # https://rpm-packaging-guide.github.io/
    run install -d BUILD
    run install -d BUILDROOT
    run install -d RPMS
    run install -d SOURCES
    run install -d SPECS
    run install -d SRPMS

    # create a fake source tarball
    run touch main.c
    run bsdtar cvaf SOURCES/src.tar.gz main.c

    cat > SPECS/pkg.spec <<EOF
Name:           $RECEIPT_PACKAGE_PKGNAME
Version:        $RECEIPT_PACKAGE_VERSION
Release:        1%{?dist}
Summary:        $RECEIPT_PACKAGE_SUMMARY
BuildArch:      $RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH

License:        $RECEIPT_PACKAGE_LICENSE
Source0:        src.tar.gz

%description
$RECEIPT_PACKAGE_SUMMARY

%prep

%build

%install
install -d %{buildroot}/usr/local
cp -r -L "$PACKAGE_INSTALLED_DIR"/* %{buildroot}/usr/local/
if [ -d %{buildroot}/usr/local/share/man ] ; then
    mv  %{buildroot}/usr/local/share/man %{buildroot}/usr/local/man
fi

%files
EOF

    # https://rpmfind.net/linux/RPM/opensuse/ports/tumbleweed/aarch64/filesystem-84.87-15.3.aarch64.html
    # these directories belong to filesystem package, it can't be included in %files
    cut -c3- < "$PACKAGE_INSTALLED_DIR/.ppkg/MANIFEST.txt" | sed -e '/^src\/$/d' -e '/^bin\/$/d' -e '/^sbin\/$/d' -e '/^lib\/$/d' -e '/^lib64\/$/d' -e '/^libexec\/$/d' -e '/^include\/$/d' -e '/^share\/$/d' -e '/^man\/$/d' -e '/^man\/man1\/$/d' -e '/^man\/man2\/$/d' -e '/^man\/man3\/$/d' -e '/^man\/man4\/$/d' -e '/^man\/man5\/$/d' -e '/^man\/man6\/$/d' -e '/^man\/man7\/$/d' -e '/^man\/man8\/$/d' -e '/^man\/man9\/$/d' -e '/^man\/mann\/$/d' -e 's|^share/man/|/man/|' -e 's|^|/usr/local/|' >> SPECS/pkg.spec

    run cat SPECS/pkg.spec

    #run rpmlint      SPECS/pkg.spec
    run rpmbuild --define "'_topdir $PWD'" -bb SPECS/pkg.spec

    run mv "RPMS/$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH/*.rpm" .

    run rpm -qlpv *.rpm
}

__export_the_given_installed_package_as_pkg() {
    # https://wiki.archlinux.org/title/PKGBUILD
    run tee PKGBUILD <<EOF
pkgname=('$RECEIPT_PACKAGE_PKGNAME')
pkgver='$RECEIPT_PACKAGE_VERSION'
pkgrel=1
pkgdesc="$RECEIPT_PACKAGE_SUMMARY"
arch=('$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH')
license=('$RECEIPT_PACKAGE_LICENSE')
url='$RECEIPT_PACKAGE_WEB_URL'
makedepends=()
source=(https://github.com/leleliu008/androidx/releases/download/v0.1.0/androidx-0.1.0.tar.gz)
sha256sums=('504601758154dd1bbf643ffe80ca49711cd5e76231ba1970a1fd88109e06fc52')

build() {
    :
}

package() {
    install -d "\${pkgdir}/usr/local"
    cp -r -L "$PACKAGE_INSTALLED_DIR"/* "\${pkgdir}/usr/local/"
}
EOF

    # https://wiki.archlinux.org/title/Makepkg

    unset CARCH
    unset CHOST

    unset LOGDEST
    unset PKGDEST
    unset SRCDEST
    unset SRCPKGDEST
    unset BUILDDIR

    export SRCEXT=".src.tar.gz"
    export PKGEXT=".pkg.tar.xz"

    export PACKAGER="leleliu008 <leleliu008@gmail.com>"

    run makepkg --nodeps --noextract --noprepare --nocheck
}

__export_the_given_installed_package_as_apk() {
    # https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package
    # https://wiki.alpinelinux.org/wiki/APKBUILD_Reference

    run export APORTSDIR="$PWD/aports"

    run export REPODEST="$PWD/packages"

    run install -d aports/community/pkg
    run cd         aports/community/pkg
    run tee APKBUILD <<EOF
# Maintainer: leleliu008 <leleliu008@gmail.com>
pkgname=$RECEIPT_PACKAGE_PKGNAME
pkgver=$RECEIPT_PACKAGE_VERSION
pkgrel=0
pkgdesc="$RECEIPT_PACKAGE_SUMMARY"
url="$RECEIPT_PACKAGE_WEB_URL"
arch="$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH"
license="$RECEIPT_PACKAGE_LICENSE"
source="https://github.com/leleliu008/test/releases/download/2023.10.08/ppkg-0.1000.2-linux-x86_64.tar.xz"
sha512sums="52206434938da1d5ead71145cc8fef1439cc567c631c7448006e835a073a8d06ef4c8f62f635927390fcf9dd4a07aadc73a29087854af4468fe914cd0b270591  ppkg-0.1000.2-linux-x86_64.tar.xz"
builddir="\$srcdir/build.d"

build() {
    :
}

check() {
    :
}

package() {
    install -d "\$pkgdir/usr/"
    cp -r -L "$PACKAGE_INSTALLED_DIR"/* "\$pkgdir/usr/"
}
EOF

    command -v abuild > /dev/null || abort 1 'abuild command not found. please install alpine-sdk package then try again.'

    run abuild -F

    run cd -
    run mv "$REPODEST/community/$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH/*.apk" .

    run bsdtar tf *.apk
}

# }}}
##############################################################################
# {{{ add_**flags

add_ccflags() {
    WRAPPER_TARGET_CCFLAGS="$WRAPPER_TARGET_CCFLAGS $*"
}

add_ldflags() {
    WRAPPER_TARGET_LDFLAGS="$WRAPPER_TARGET_LDFLAGS $*"
}

# }}}
##############################################################################
# {{{ cabal_v2_install

# https://cabal.readthedocs.io/en/3.14/cabal-project-description-file.html
cabal_v2_install() {
    if [ -z "$BOOTSTRAP_HASKELL_GHC_VERSION" ] ; then
        if [ -f cabal.project ] ; then
            HASKELL_GHC_VERSION="$(gsed -n '/^with-compiler: ghc-/p' cabal.project)"

            if [ -n "$HASKELL_GHC_VERSION" ] ; then
                HASKELL_GHC_VERSION="${HASKELL_GHC_VERSION#'with-compiler: ghc-'}"

                if [ -n "$HASKELL_GHC_VERSION" ] ; then
                    export BOOTSTRAP_HASKELL_GHC_VERSION="$HASKELL_GHC_VERSION"
                fi
            fi
        fi

        if [ -z "$BOOTSTRAP_HASKELL_GHC_VERSION" ] ; then
            export BOOTSTRAP_HASKELL_GHC_VERSION='9.8.2'
        fi
    fi

    export BOOTSTRAP_HASKELL_CABAL_VERSION='3.14.1.1'
    export BOOTSTRAP_HASKELL_NONINTERACTIVE=1
    export BOOTSTRAP_HASKELL_VERBOSE=1
    export BOOTSTRAP_HASKELL_INSTALL_NO_STACK=1

    unset  BOOTSTRAP_HASKELL_INSTALL_HLS
    unset  BOOTSTRAP_HASKELL_CABAL_XDG
    unset  BOOTSTRAP_HASKELL_DOWNLOADER
    unset  BOOTSTRAP_HASKELL_ADJUST_BASHRC
    unset  BOOTSTRAP_HASKELL_MINIMAL

    unset  GHCUP_USE_XDG_DIRS
    unset  GHCUP_BASE_URL

    export GHCUP_INSTALL_BASE_PREFIX="$PACKAGE_WORKING_DIR"

    if [ "$GITHUB_ACTIONS" = true ] ; then
        DEBUG_CABAL=1
    fi

    wfetch 'https://get-ghcup.haskell.org' -o ghcup-installer.sh
    gsed -i '/GHCUP_INSTALL_BASE_PREFIX:=/d'  ghcup-installer.sh
    run sh ghcup-installer.sh

    export LD_LIBRARY_PATH="$libncurses_LIBRARY_DIR:$libgmp_LIBRARY_DIR"

    export WRAPPER_TARGET_CCFLAGS="$WRAPPER_TARGET_CCFLAGS -L$PACKAGE_WORKING_DIR/lib"
    export WRAPPER_TARGET_CXXFLAGS="$WRAPPER_TARGET_CXXFLAGS -L$PACKAGE_WORKING_DIR/lib"

    export PATH="$GHCUP_INSTALL_BASE_PREFIX/.ghcup/bin:$PATH"

    if [ "$TARGET_PLATFORM_VERS" = glibc ] ; then
        X="$("$CC_FOR_BUILD" -print-file-name=libtinfo.so.6)"

        if [ -n "$X" ] ; then
            run ln -s "$X" "$PACKAGE_WORKING_DIR/lib/libtinfo.so"
        fi
    fi

    ##############################################################################

    export IFS=':'

    CABAL_PROJECT_EXTRA_INCLUDE_DIRS="$PACKAGE_WORKING_DIR/include"

    for item in $TARGET_INCLUDE_SEARCH_DIRS
    do
        CABAL_PROJECT_EXTRA_INCLUDE_DIRS="$CABAL_PROJECT_EXTRA_INCLUDE_DIRS,$item"
    done

    CABAL_PROJECT_EXTRA_LIBRARY_DIRS="$PACKAGE_WORKING_DIR/lib"

    for item in $TARGET_LIBRARY_SEARCH_DIRS
    do
        CABAL_PROJECT_EXTRA_LIBRARY_DIRS="$CABAL_PROJECT_EXTRA_LIBRARY_DIRS,$item"
    done

    unset IFS

    ##############################################################################

    if [ ! -f cabal.project ] ; then
        cat > cabal.project <<EOF
packages: ./*.cabal
EOF
    fi

    cat >> cabal.project <<EOF

package *
    extra-include-dirs: $CABAL_PROJECT_EXTRA_INCLUDE_DIRS
    extra-lib-dirs: $CABAL_PROJECT_EXTRA_LIBRARY_DIRS

EOF

    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        cat >> cabal.project <<EOF
    ld-options: -static
EOF
    fi

    ##############################################################################

    CABAL_ARGS="--jobs=$BUILD_NJOBS --max-backjumps=100000 --install-method=copy --installdir=$PACKAGE_INSTALL_DIR/bin"

    if [ "$VERBOSE_CABAL" = 1 ] ; then
        CABAL_ARGS="$CABAL_ARGS -v2"
    fi

    if [ "$DEBUG_CABAL" = 1 ] ; then
        CABAL_ARGS="$CABAL_ARGS -v3"
    fi

    if [ "$ENABLE_STRIP" = 1 ] ; then
        CABAL_ARGS="$CABAL_ARGS --enable-executable-stripping"
    fi

    CABAL=$(command -v cabal) || abort 1 "command not found: cabal"

    run "$CABAL" --version
    run "$CABAL" update
    run "$CABAL" v2-install "$CABAL_ARGS" "$@"
}

# }}}
##############################################################################
# {{{ netsurf_buildsystem

netsurf_buildsystem() {
    gmakew install COMPONENT_TYPE=lib-static NSSHARED="$NATIVE_PACKAGE_INSTALLED_ROOT/netsurf_buildsystem/share/netsurf-buildsystem" PREFIX="$PACKAGE_INSTALL_DIR"
    gmakew install COMPONENT_TYPE=lib-shared NSSHARED="$NATIVE_PACKAGE_INSTALLED_ROOT/netsurf_buildsystem/share/netsurf-buildsystem" PREFIX="$PACKAGE_INSTALL_DIR"
}

# }}}
##############################################################################
# {{{ waf

waf() {
    PYTHON3=$(command -v python3) || abort 1 "command not found: python3"

    run "$PYTHON3" ./waf configure --prefix=$PACKAGE_INSTALL_DIR $@
    run "$PYTHON3" ./waf build
    run "$PYTHON3" ./waf install
}

# }}}
##############################################################################
# {{{ zig

zig() {
    ZIG_BUILD_EXTRA_ARGS="-j$BUILD_NJOBS"

    if [ "$TARGET_PLATFORM_NAME" = macos ] ; then
        # https://zig.guide/build-system/cross-compilation/
        if [ $TARGET_PLATFORM_ARCH = arm64 ] ; then
            ZIG_BUILD_TARGET='aarch64-macos'
        else
            ZIG_BUILD_TARGET=$TARGET_PLATFORM_ARCH-macos
        fi

        ZIG_BUILD_EXTRA_ARGS="$ZIG_BUILD_EXTRA_ARGS -Dtarget=$ZIG_BUILD_TARGET"
    fi

    case $PROFILE in
        release) ZIG_BUILD_EXTRA_ARGS="$ZIG_BUILD_EXTRA_ARGS --release=small" ;;
    esac

    if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_NORMAL" ] ; then
        ZIG_BUILD_EXTRA_ARGS="$ZIG_BUILD_EXTRA_ARGS --verbose"
    fi

    run command zig build $ZIG_BUILD_EXTRA_ARGS --prefix "$PACKAGE_INSTALL_DIR" "$@"
}


# }}}
##############################################################################
# {{{ configure

configure() {
    unset CONFIGURE_ONLY

    if [ "$1" = only ] ; then
        CONFIGURE_ONLY=1
        shift
    fi

    export FORCE_UNSAFE_CONFIGURE=1

    export ac_cv_func_malloc_0_nonnull=yes
    export ac_cv_func_calloc_0_nonnull=yes
    export ac_cv_func_realloc_0_nonnull=yes

    CONFIGURE_ARGS="--prefix=$PACKAGE_INSTALL_DIR --disable-option-checking"

    if [ "$BUILD_FOR_NATIVE" = 1 ] ; then
        if run "$PACKAGE_BSCRIPT_DIR"/configure $CONFIGURE_ARGS $@ ; then
            echo
        else
            if [ -f "$PACKAGE_BCACHED_DIR/config.log" ] ; then
                run cat "$PACKAGE_BCACHED_DIR/config.log"
            elif [ -f "$PACKAGE_BSCRIPT_DIR/config.log" ] ; then
                run cat "$PACKAGE_BSCRIPT_DIR/config.log"
            fi
            return 1
        fi
    else
        if [ "$CROSS_COMPILING" = 1 ] ; then
            if [ "$TARGET_PLATFORM_NAME" = linux ] ; then
                case $TARGET_PLATFORM_VERS in
                    glibc) TARGET_TRIPLE="$TARGET_PLATFORM_ARCH-unknown-linux-gnu"  ;;
                    musl)  TARGET_TRIPLE="$TARGET_PLATFORM_ARCH-unknown-linux-musl" ;;
                    *)     TARGET_TRIPLE="$TARGET_PLATFORM_ARCH-unknown-linux"
                esac
            elif [ "$TARGET_PLATFORM_NAME" = macos ] ; then
                TARGET_TRIPLE="$TARGET_PLATFORM_ARCH-apple-darwin"
            else
                TARGET_TRIPLE="$TARGET_PLATFORM_ARCH-unknown-$TARGET_PLATFORM_NAME"
            fi

            CONFIGURE_ARGS="$CONFIGURE_ARGS --host=$TARGET_TRIPLE"
        fi

        CONFIGURE_ARG_ENABLE_NLS=0
        CONFIGURE_ARG_ENABLE_RPATH=0
        CONFIGURE_ARG_ENABLE_LARGEFILE=1

        CONFIGURE_ARG_ENABLE_DEBUG=
        CONFIGURE_ARG_ENABLE_STATIC=
        CONFIGURE_ARG_ENABLE_SHARED=

        for arg in "$@"
        do
            case $arg in
                --enable-nls)      CONFIGURE_ARG_ENABLE_NLS=1 ;;
                --enable-nls=yes)  CONFIGURE_ARG_ENABLE_NLS=1 ;;
                --enable-nls=no)   CONFIGURE_ARG_ENABLE_NLS=0 ;;
                --disable-nls)     CONFIGURE_ARG_ENABLE_NLS=0 ;;

                --enable-rpath)     CONFIGURE_ARG_ENABLE_RPATH=1 ;;
                --enable-rpath=yes) CONFIGURE_ARG_ENABLE_RPATH=1 ;;
                --enable-rpath=no)  CONFIGURE_ARG_ENABLE_RPATH=0 ;;
                --disable-rpath)    CONFIGURE_ARG_ENABLE_RPATH=0 ;;

                --enable-largefile)     CONFIGURE_ARG_ENABLE_LARGEFILE=1 ;;
                --enable-largefile=yes) CONFIGURE_ARG_ENABLE_LARGEFILE=1 ;;
                --enable-largefile=no)  CONFIGURE_ARG_ENABLE_LARGEFILE=0 ;;
                --disable-largefile)    CONFIGURE_ARG_ENABLE_LARGEFILE=0 ;;

                --enable-debug)     CONFIGURE_ARG_ENABLE_DEBUG=1 ;;
                --enable-debug=yes) CONFIGURE_ARG_ENABLE_DEBUG=1 ;;
                --enable-debug=no)  CONFIGURE_ARG_ENABLE_DEBUG=0 ;;
                --disable-debug)    CONFIGURE_ARG_ENABLE_DEBUG=0 ;;

                --enable-static)     CONFIGURE_ARG_ENABLE_STATIC=1 ;;
                --enable-static=yes) CONFIGURE_ARG_ENABLE_STATIC=1 ;;
                --enable-static=no)  CONFIGURE_ARG_ENABLE_STATIC=0 ;;
                --disable-static)    CONFIGURE_ARG_ENABLE_STATIC=0 ;;

                --enable-shared)     CONFIGURE_ARG_ENABLE_SHARED=1 ;;
                --enable-shared=yes) CONFIGURE_ARG_ENABLE_SHARED=1 ;;
                --enable-shared=no)  CONFIGURE_ARG_ENABLE_SHARED=0 ;;
                --disable-shared)    CONFIGURE_ARG_ENABLE_SHARED=0 ;;
            esac
        done

        if [ "$CONFIGURE_ARG_ENABLE_NLS" = 1 ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-nls"
        else
            CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-nls"
        fi

        if [ "$CONFIGURE_ARG_ENABLE_RPATH" = 1 ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-rpath"
        else
            CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-rpath"
        fi

        if [ "$CONFIGURE_ARG_ENABLE_LARGEFILE" = 1 ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-largefile"
        else
            CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-largefile"
        fi

        if [ -z "$CONFIGURE_ARG_ENABLE_DEBUG" ] ; then
            case $PROFILE in
                debug)   CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-debug"  ;;
                release) CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-debug" ;;
            esac
        fi

        if [ -z "$CONFIGURE_ARG_ENABLE_STATIC" ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-static"
        fi

        if [ -z "$CONFIGURE_ARG_ENABLE_SHARED" ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-shared"
        fi

        # https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md#is-32_bit-on-lp32-y2038
        if [ "$TARGET_PLATFORM_NBIT" = 32 ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-year2038"
        fi

        CONFIGURE_ENVS="$CONFIGURE_ENVS
            CC='$CC'
            CFLAGS='$CFLAGS'
            CXX='$CXX'
            CXXFLAGS='$CXXFLAGS'
            CPP='$CPP'
            CPPFLAGS='$CPPFLAGS'
            LDFLAGS='$LDFLAGS'
            AR='$AR'
            RANLIB='$RANLIB'
            PKG_CONFIG='$PKG_CONFIG'
            PKG_CONFIG_PATH='$PKG_CONFIG_PATH'
            PKG_CONFIG_LIBDIR='$PKG_CONFIG_LIBDIR'
            CC_FOR_BUILD='$CC_FOR_BUILD'"

        CONFIGURE="$PACKAGE_BSCRIPT_DIR/configure"

        if [ "$CROSS_COMPILING" = 1 ] ; then
            gsed -i 's/cross_compiling=no/cross_compiling=yes/g' "$CONFIGURE"
        fi

        if run $CONFIGURE $CONFIGURE_ARGS $@ $CONFIGURE_ENVS ; then
            echo
        else
            # https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
            if [ "$GITHUB_ACTIONS" = true ] ; then
                if [ -f "$PACKAGE_BCACHED_DIR/config.log" ] ; then
                    run cat "$PACKAGE_BCACHED_DIR/config.log"
                elif [ -f "$PACKAGE_BSCRIPT_DIR/config.log" ] ; then
                    run cat "$PACKAGE_BSCRIPT_DIR/config.log"
                fi
            fi
            return 1
        fi
    fi

    if [ "$VERBOSE_GMAKE" = 1 ] ; then
        find "$PACKAGE_BSCRIPT_DIR" -type f -name Makefile -exec gsed -i -e 's|\t@|\t|g' -e 's|@echo|echo|g' {} +
    fi

    if [ "$CONFIGURE_ONLY" != 1 ] ; then
        gmakew clean
        gmakew
        gmakew install
    fi
}

# }}}
##############################################################################
# {{{ ninjaw

ninjaw() {
    run ninja "$@"
}

# }}}
##############################################################################
# {{{ gmakew

gmakew() {
    unset GMAKE_OPTIONS
    unset GMAKE_OPTION_SET_C
    unset GMAKE_OPTION_SET_w
    unset GMAKE_OPTION_SET_j

    for option in $@
    do
        case $option in
            -C)           GMAKE_OPTION_SET_C=1 ;;
            -w)           GMAKE_OPTION_SET_w=1 ;;
            -j)           GMAKE_OPTION_SET_j=1 ;;
            -j[1-9])      GMAKE_OPTION_SET_j=1 ;;
            -j[1-9][0-9]) GMAKE_OPTION_SET_j=1 ;;
        esac
    done

    if [ "$GMAKE_OPTION_SET_w" != 1 ] ; then
        GMAKE_OPTIONS="$GMAKE_OPTIONS -w"
    fi

    if [ "$GMAKE_OPTION_SET_C" != 1 ] ; then
        if [ "$PACKAGE_BINBSTD" != 1 ] ; then
            GMAKE_OPTIONS="$GMAKE_OPTIONS -C $PACKAGE_BCACHED_DIR"
        fi
    fi

    if [ "$GMAKE_OPTION_SET_j" != 1 ] ; then
        GMAKE_OPTIONS="$GMAKE_OPTIONS -j$BUILD_NJOBS"
    fi

    if [ "$VERBOSE_GMAKE" = 1 ] ; then
        GMAKE_OPTIONS="$GMAKE_OPTIONS V=1"
    fi

    if [ "$DEBUG_GMAKE" = 1 ] ; then
        GMAKE_OPTIONS="$GMAKE_OPTIONS --debug"
    fi

    if [ "$VERBOSE_GMAKE" = 1 ] ; then
        find "$PACKAGE_BSCRIPT_DIR" -type f -name Makefile -exec gsed -i -e 's|\t@|\t|g' -e 's|@echo|echo|g' {} +
    fi

    if [ "$REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON" = 1 ] && [ "$BEAR_ENABLED" = 1 ] ; then
        run bear -- $GMAKE $GMAKE_OPTIONS $*
    else
        run         $GMAKE $GMAKE_OPTIONS $*
    fi
}

# }}}
##############################################################################
# {{{ cmakew

# cmakew [2] [--targets=<comma-separated list>] [--components=<comma-separated list>] [CMAKE-OPTIONS]
cmakew() {
    unset CMAKE_EXTRA_ARGS
    unset CMAKE_BUILD_TARGETS
    unset CMAKE_INSTALL_COMPONENTS
    unset CMAKE_BUILD_STATIC_SHARED_LIBRARY_SEPARATEDLY

    if [ "$1" = 2 ] ; then
        CMAKE_BUILD_STATIC_SHARED_LIBRARY_SEPARATEDLY=1
        shift
    fi

    while [ -n "$1" ]
    do
        case $1 in
            -S) shift; PACKAGE_BSCRIPT_DIR="$1" ;;
            -B) shift; PACKAGE_BCACHED_DIR="$1" ;;
            --targets=*)
                TARGETS="${1#*=}"

                export IFS=','

                for item in $TARGETS
                do
                    CMAKE_BUILD_TARGETS="$CMAKE_BUILD_TARGETS $item"
                done

                unset IFS
                ;;
            --components=*)
                COMPONENTS="${1#*=}"

                export IFS=','

                for item in $COMPONENTS
                do
                    CMAKE_INSTALL_COMPONENTS="$CMAKE_INSTALL_COMPONENTS $item"
                done

                unset IFS
                ;;
            *)  CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS $1"
        esac
        shift
    done

    if [ "$CMAKE_BUILD_STATIC_SHARED_LIBRARY_SEPARATEDLY" = 1 ] ; then
        cmakew_internal $CMAKE_EXTRA_ARGS -DBUILD_SHARED_LIBS=OFF
        cmakew_internal $CMAKE_EXTRA_ARGS -DBUILD_SHARED_LIBS=ON
    else
        cmakew_internal $CMAKE_EXTRA_ARGS
    fi
}

cmakew_internal() {
    if [ "$BUILD_FOR_NATIVE" = 1 ] ; then
        cmakew_for_native "$@"
    else
        cmakew_for_target "$@"
    fi
}

cmakew_for_native() {
    if [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] ; then
        export CMAKE_GENERATOR='Ninja'
    else
        export CMAKE_GENERATOR='Unix Makefiles'
    fi

    if [ "$VERBOSE_CMAKE" = 1 ] ; then
        CMAKE_VERBOSE_MAKEFILE=ON
        CMAKE_COLOR_MAKEFILE=ON
    else
        CMAKE_VERBOSE_MAKEFILE=OFF
        CMAKE_COLOR_MAKEFILE=OFF
    fi

    if [ "$DEBUG_CMAKE" = 1 ] ; then
        CMAKE_FIND_DEBUG_MODE=ON
    else
        CMAKE_FIND_DEBUG_MODE=OFF
    fi

    run "$CMAKE" \
        -Wno-dev \
        -S "$PACKAGE_BSCRIPT_DIR" \
        -B "$PACKAGE_BCACHED_DIR" \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX="$PACKAGE_INSTALL_DIR" \
        -DCMAKE_FIND_DEBUG_MODE="$CMAKE_FIND_DEBUG_MODE" \
        -DCMAKE_VERBOSE_MAKEFILE="$CMAKE_VERBOSE_MAKEFILE" \
        -DCMAKE_COLOR_MAKEFILE="$CMAKE_COLOR_MAKEFILE" \
        -DBUILD_SHARED_LIBS=OFF \
        -DBUILD_TESTING=OFF \
        "$@" &&
    run "$CMAKE" --build   "$PACKAGE_BCACHED_DIR" &&
    run "$CMAKE" --install "$PACKAGE_BCACHED_DIR"
}

cmakew_for_target() {
    echo "CMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE"

    cat > "$CMAKE_TOOLCHAIN_FILE" <<EOF
message(STATUS "CMake command: \${CMAKE_COMMAND}")
message(STATUS "CMake version: \${CMAKE_VERSION}")
EOF

    if [ "$CROSS_COMPILING" = 1 ] ; then
        case $TARGET_PLATFORM_NAME in
            linux)    CMAKE_SYSTEM_NAME=Linux   ;;
            macos)    CMAKE_SYSTEM_NAME=Darwin  ;;
            freebsd)  CMAKE_SYSTEM_NAME=FreeBSD ;;
            openbsd)  CMAKE_SYSTEM_NAME=OpenBSD ;;
            netbsd)   CMAKE_SYSTEM_NAME=NetBSD  ;;
            dragonflybsd)
                      CMAKE_SYSTEM_NAME=DragonFly ;;
            *)        CMAKE_SYSTEM_NAME="$TARGET_PLATFORM_NAME"
        esac

        cat >> "$CMAKE_TOOLCHAIN_FILE" <<EOF
set(CMAKE_SYSTEM_NAME      $CMAKE_SYSTEM_NAME)
set(CMAKE_SYSTEM_VERSION   $TARGET_PLATFORM_VERS)
set(CMAKE_SYSTEM_PROCESSOR $TARGET_PLATFORM_ARCH)
EOF
    fi

    cat >> "$CMAKE_TOOLCHAIN_FILE" <<EOF

message(STATUS "CMAKE_HOST_SYSTEM_NAME: \${CMAKE_HOST_SYSTEM_NAME}")
message(STATUS "     CMAKE_SYSTEM_NAME: \${CMAKE_SYSTEM_NAME}")

if ("\${BUILD_SHARED_LIBS}" STREQUAL "")
    set(BUILD_SHARED_LIBS $BUILD_SHARED_LIBS)
endif()

set(CMAKE_BUILD_TYPE  $CMAKE_BUILD_TYPE)

set(CMAKE_C_COMPILER "$CC")
set(CMAKE_C_FLAGS "$CPPFLAGS $CFLAGS")

set(CMAKE_CXX_COMPILER "$CXX")
set(CMAKE_CXX_FLAGS "$CPPFLAGS $CXXFLAGS")

set(CMAKE_ASM_COMPILER "$CC")

set(CMAKE_SHARED_LINKER_FLAGS "$LDFLAGS")
set(CMAKE_EXE_LINKER_FLAGS    "$LDFLAGS")

set(CMAKE_C_COMPILER_AR     "$AR")
set(CMAKE_C_COMPILER_RANLIB "$RANLIB")

set(CMAKE_CXX_COMPILER_AR     "$AR")
set(CMAKE_CXX_COMPILER_RANLIB "$RANLIB")

set(CMAKE_AR      "$AR")
set(CMAKE_RANLIB  "$RANLIB")

set(CMAKE_LINKER  "$LD")

set(CMAKE_NM      "$NM")
set(CMAKE_READELF "$READELF")

set(CMAKE_OBJCOPY "$OBJCOPY")
set(CMAKE_OBJDUMP "$OBJDUMP")

set(CMAKE_STRIP   "$STRIP")

set(CMAKE_ADDR2LINE "$ADDR2LINE")

set(CMAKE_FIND_DEBUG_MODE $CMAKE_FIND_DEBUG_MODE)
set(CMAKE_FIND_ROOT_PATH "$CMAKE_FIND_ROOT_PATH")
EOF

    if [ "$CROSS_COMPILING" = 1 ] ; then
        cat >> "$CMAKE_TOOLCHAIN_FILE" <<EOF
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
EOF
    fi

    if [ "$TARGET_PLATFORM_NAME" = macos ] ; then
        cat >> "$CMAKE_TOOLCHAIN_FILE" <<EOF
# https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_ARCHITECTURES.html
set(CMAKE_OSX_ARCHITECTURES "$TARGET_PLATFORM_ARCH" CACHE STRING "")
EOF
    fi

    if [ "$VERBOSE_CMAKE" = 1 ] ; then
        if command -v bat > /dev/null ; then
            run bat --language=cmake --paging=never --style=plain "$CMAKE_TOOLCHAIN_FILE"
        else
            run cat "$CMAKE_TOOLCHAIN_FILE"
        fi
    fi

    # https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_INCLUDE.html
    CMAKE_PROJECT_INCLUDE="$PACKAGE_WORKING_DIR/project-after.cmake"

    # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_LIBRARY_SUFFIXES.html
    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        printf 'set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")\n'       > "$CMAKE_PROJECT_INCLUDE"
    elif [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        printf 'set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".so")\n' > "$CMAKE_PROJECT_INCLUDE"
    fi

    if [ "$VERBOSE_CMAKE" = 1 ] && [ -f "$CMAKE_PROJECT_INCLUDE" ] ; then
        run cat "$CMAKE_PROJECT_INCLUDE"
    fi

    if [   -f "$PACKAGE_BCACHED_DIR/CMakeCache.txt" ] ; then
        rm -f "$PACKAGE_BCACHED_DIR/CMakeCache.txt"
    fi

    CMAKE_CONFIG_OPTIONS="-Wno-dev -DBUILD_TESTING=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_PREFIX='$PACKAGE_INSTALL_DIR' -DCMAKE_TOOLCHAIN_FILE='$CMAKE_TOOLCHAIN_FILE' -DCMAKE_VERBOSE_MAKEFILE='$CMAKE_VERBOSE_MAKEFILE' -DCMAKE_COLOR_MAKEFILE='$CMAKE_COLOR_MAKEFILE'"

    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        CMAKE_CONFIG_OPTIONS="$CMAKE_CONFIG_OPTIONS -DCMAKE_SKIP_INSTALL_RPATH=TRUE"
    fi

    if [ -f "$CMAKE_PROJECT_INCLUDE" ] ; then
        CMAKE_CONFIG_OPTIONS="$CMAKE_CONFIG_OPTIONS -DCMAKE_PROJECT_INCLUDE=$CMAKE_PROJECT_INCLUDE"
    fi

    # https://cmake.org/cmake/help/latest/manual/cmake.1.html
    run "$CMAKE" "$CMAKE_CONFIG_OPTIONS" -S "$PACKAGE_BSCRIPT_DIR" -B "$PACKAGE_BCACHED_DIR" "$@"

    if [ "$GITHUB_ACTIONS" = true ] ; then
        CMAKE_CONFIGURE_LOG_FILEPATH="$PACKAGE_BCACHED_DIR/CMakeFiles/CMakeConfigureLog.yaml"

        if [ -f "$CMAKE_CONFIGURE_LOG_FILEPATH" ] ; then
            run cat "$CMAKE_CONFIGURE_LOG_FILEPATH"
        fi
    fi

    if [ -z "$CMAKE_BUILD_TARGETS" ] ; then
        run "$CMAKE" --build   "$PACKAGE_BCACHED_DIR"
    else
        run "$CMAKE" --build   "$PACKAGE_BCACHED_DIR" --target "$CMAKE_BUILD_TARGETS"
    fi

    if [ -z "$CMAKE_INSTALL_COMPONENTS" ] ; then
        run "$CMAKE" --install "$PACKAGE_BCACHED_DIR"
    else
        for component in $CMAKE_INSTALL_COMPONENTS
        do
        run "$CMAKE" --install "$PACKAGE_BCACHED_DIR" --component "$component"
        done
    fi
}

# }}}
##############################################################################
# {{{ xmakew

# https://github.com/xmake-io/xmake/issues/2003
# run in a subshell
xmakew() {
    XMAKE_CONFIG_OPTIONS="$*"

    XMAKE_CONFIG_OPTION_CLEAN=
    XMAKE_CONFIG_OPTION_MODE=
    XMAKE_CONFIG_OPTION_vD=

    for arg in "$@"
    do
        case $arg in
            -c|--clean)  XMAKE_CONFIG_OPTION_CLEAN='set' ;;
            -m|--mode=*) XMAKE_CONFIG_OPTION_MODE='set'  ;;
            -vD)         XMAKE_CONFIG_OPTION_vD='set' ;;
        esac
    done

    if [ "$DEBUG_XMAKE" = 1 ] && [ -z "$XMAKE_CONFIG_OPTION_vD" ]; then
        XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTION_vD -vD"
    fi

    if [ -z "$XMAKE_CONFIG_OPTION_CLEAN" ] ; then
        XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --clean"
    fi

    if [ -z "$XMAKE_CONFIG_OPTION_MODE" ] ; then
        XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --mode=$PROFILE"
    fi

    run "$XMAKE" config "$XMAKE_CONFIG_OPTIONS" "--project=$PACKAGE_BSCRIPT_DIR" "--buildir=$PACKAGE_BCACHED_DIR" "--cc=$CC" "--cxx=$CXX" "--as=$CC" "--ld=$CC" "--cflags='$CFLAGS $CPPFLAGS'" "--cxxflags='$CXXFLAGS $CPPFLAGS'" "--ldflags='$LDFLAGS'" "--shflags='$LDFLAGS'" &&
    run "$XMAKE" "--jobs=$BUILD_NJOBS" &&
    run "$XMAKE" install -o "$PACKAGE_INSTALL_DIR"
}

# }}}
##############################################################################
# {{{ mesonw

# https://mesonbuild.com/Native-environments.html
# https://mesonbuild.com/Cross-compilation.html
mesonw() {
    MESON_NATIVE_FILE="$PACKAGE_WORKING_DIR/native-file.ini"

    cat > "$MESON_NATIVE_FILE" <<EOF
[binaries]
c = '$CC'
cpp = '$CXX'
ar = '$AR'
strip = '$STRIP'
cmake = '$CMAKE'
pkg-config = '$PKG_CONFIG'

[built-in options]
c_args = $(to_meson_array $CFLAGS $CPPFLAGS)
c_link_args = $(to_meson_array $LDFLAGS)
cpp_args = $(to_meson_array $CXXFLAGS $CPPFLAGS)
cpp_link_args = $(to_meson_array $LDFLAGS)
EOF

    MESON_SETUP_ARGS="--prefix=$PACKAGE_INSTALL_DIR --buildtype=$PROFILE --backend=ninja --pkg-config-path=$PKG_CONFIG_PATH --build.pkg-config-path=$PKG_CONFIG_PATH_FOR_BUILD --native-file=$MESON_NATIVE_FILE -Dlibdir=lib"

    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        MESON_SETUP_ARGS="$MESON_SETUP_ARGS -Ddefault_library=static --prefer-static"
    else
        MESON_SETUP_ARGS="$MESON_SETUP_ARGS -Ddefault_library=both"
    fi

    MESON_COMPILE_ARGS="-C $PACKAGE_BCACHED_DIR -j $BUILD_NJOBS"
    MESON_INSTALL_ARGS="-C $PACKAGE_BCACHED_DIR"

    if [ "$VERBOSE_MESON" = 1 ] ; then
        MESON_COMPILE_ARGS="$MESON_COMPILE_ARGS -v"
    fi

    run "$MESON" setup "$MESON_SETUP_ARGS" "$@" "$PACKAGE_BCACHED_DIR" "$PACKAGE_BSCRIPT_DIR" || {
        if [ "$GITHUB_ACTIONS" = true ] ; then
            MESON_LOG_FILEPATH="$PACKAGE_BCACHED_DIR/meson-logs/meson-log.txt"

            if [ -f "$MESON_LOG_FILEPATH" ] ; then
                run cat "$MESON_LOG_FILEPATH"
            fi
        fi
        exit 1
    }

    run "$MESON" compile "$MESON_COMPILE_ARGS"
    run "$MESON" install "$MESON_INSTALL_ARGS"
}

to_meson_array() {
    RESULT=

    for item in "$@"
    do
        if [ -z "$RESULT" ] ; then
            RESULT="'$item'"
        else
            RESULT="$RESULT, '$item'"
        fi
    done

    printf '[%s]\n' "$RESULT"
}

# }}}
##############################################################################
# {{{ cargow

cargow() {
    command -v rustup > /dev/null && run rustup target add "$RUST_TARGET"

    case $1 in
        build)
            # https://doc.rust-lang.org/cargo/commands/cargo-clean.html
            # https://doc.rust-lang.org/cargo/commands/cargo-build.html

            unset CARGO_BUILD_ARGS
            unset CARGO_BUILD_ARG_VV
            unset CARGO_BUILD_ARG_TARGET
            unset CARGO_BUILD_ARG_RELEASE

            for arg in "$@"
            do
                case $arg in
                    --vv)      CARGO_BUILD_ARG_VV='set'      ;;
                    --target)  CARGO_BUILD_ARG_TARGET='set'  ;;
                    --release) CARGO_BUILD_ARG_RELEASE='set' ;;
                esac
            done

            CARGO_BUILD_ARGS="$*"

            if [ -z "$CARGO_BUILD_ARG_VV" ] ; then
                CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS -vv"
            fi

            if [ -z "$CARGO_BUILD_ARG_RELEASE" ] ; then
                CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS --release"
            fi

            if [ -z "$CARGO_BUILD_ARG_TARGET" ] ; then
                CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS --target $RUST_TARGET"
            fi

            # shellcheck disable=SC2086
            run cargo clean && run cargo $CARGO_BUILD_ARGS
            ;;
        install)
            # https://doc.rust-lang.org/cargo/commands/cargo-clean.html
            # https://doc.rust-lang.org/cargo/commands/cargo-install.html

            unset CARGO_INSTALL_ARGS
            unset CARGO_INSTALL_ARG_TARGET
            unset CARGO_INSTALL_ARG_PATH
            unset CARGO_INSTALL_ARG_ROOT
            unset CARGO_INSTALL_ARG_VV

            for arg in "$@"
            do
                case $arg in
                    --target) CARGO_INSTALL_ARG_TARGET='set' ;;
                    --path)   CARGO_INSTALL_ARG_PATH='set'   ;;
                    --root)   CARGO_INSTALL_ARG_ROOT='set'   ;;
                    --vv)     CARGO_INSTALL_ARG_VV='set'     ;;
                esac
            done

            CARGO_INSTALL_ARGS="$*"

            if [ -z "$CARGO_INSTALL_ARG_VV" ] ; then
                CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS -vv"
            fi

            if [ -z "$CARGO_INSTALL_ARG_TARGET" ] ; then
                CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS --target $RUST_TARGET"
            fi

            if [ -z "$CARGO_INSTALL_ARG_PATH" ] ; then
                CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS --path $PACKAGE_BSCRIPT_DIR"
            fi

            if [ -z "$CARGO_INSTALL_ARG_ROOT" ] ; then
                CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS --root=$PACKAGE_INSTALL_DIR"
            fi

            # shellcheck disable=SC2086
            run cargo clean && run cargo $CARGO_INSTALL_ARGS
            ;;
        cbuild|cinstall)
            unset CARGO_CINSTALL_ARGS
            unset CARGO_CINSTALL_ARG_Q
            unset CARGO_CINSTALL_ARG_V
            unset CARGO_CINSTALL_ARG_VV
            unset CARGO_CINSTALL_ARG_DEBUG
            unset CARGO_CINSTALL_ARG_RELEASE
            unset CARGO_CINSTALL_ARG_TARGET
            unset CARGO_CINSTALL_ARG_PREFIX

            for arg in "$@"
            do
                case $arg in
                    -q|--quiet)   CARGO_CINSTALL_ARG_Q='set'       ;;
                    -v|--verbose) CARGO_CINSTALL_ARG_V='set'       ;;
                    -vv)          CARGO_CINSTALL_ARG_VV='set'      ;;
                    --debug)      CARGO_CINSTALL_ARG_DEBUG='set'   ;;
                    --release)    CARGO_CINSTALL_ARG_RELEASE='set' ;;
                    --target)     CARGO_CINSTALL_ARG_TARGET='set'  ;;
                    --prefix)     CARGO_CINSTALL_ARG_PREFIX='set'  ;;
                esac
            done

            CARGO_CINSTALL_ARGS="$*"

            if [ -z "$CARGO_CINSTALL_ARG_Q" ] && [ -z "$CARGO_CINSTALL_ARG_V" ] && [ -z "$CARGO_CINSTALL_ARG_VV" ] ; then
                CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS -vv"
            fi

            if [ -z "$CARGO_CINSTALL_ARG_DEBUG" ] && [ -z "$CARGO_CINSTALL_ARG_RELEASE" ] ; then
                CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS --release"
            fi

            if [ -z "$CARGO_CINSTALL_ARG_TARGET" ] ; then
                CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS --target $RUST_TARGET"
            fi

            if [ -z "$CARGO_CINSTALL_ARG_PREFIX" ] ; then
                CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS --prefix $PACKAGE_INSTALL_DIR"
            fi

            # shellcheck disable=SC2086
            run cargo $CARGO_CINSTALL_ARGS
            ;;
        *) cargo "$@"
    esac
}

# }}}
##############################################################################
# {{{ gow

gow() {
    if command -v bat > /dev/null ; then
        run "go env | bat --language=bash --paging=never --style=plain"
    else
        run "go env"
    fi

    printf '\n'

    # /Users/runner/go/pkg/mod/golang.org/x/sys@v0.0.0-20191028164358-195ce5e7f934/unix/syscall_darwin.1_13.go:25:3: //go:linkname must refer to declared function or variable
    if [ "$TARGET_PLATFORM_NAME" = macos ] ; then
        GOMOD="$PACKAGE_BSCRIPT_DIR/go.mod"

        if [ -f "$GOMOD" ] && go mod graph | grep -q 'golang\.org/x/sys' ; then
            run go get -u golang.org/x/sys

            if [ -d "$PACKAGE_BSCRIPT_DIR/vendor" ] ; then
                unset GO_VERSION_MAJOR
                unset GO_VERSION_MINOR

                GO_VERSION_MAJOR=$(go env GOVERSION | cut -c3- | cut -d. -f1)
                GO_VERSION_MINOR=$(go env GOVERSION | cut -c3- | cut -d. -f2)

                gsed -i "/^go[[:space:]]*[1-9]\.[0-9][0-9]/c go $GO_VERSION_MAJOR.$GO_VERSION_MINOR" "$GOMOD"
                gsed -i 's|^go 1.22$|go 1.22.0|' "$GOMOD"

                run go mod tidy
                run go mod vendor
            fi
        fi
    fi

    # https://pkg.go.dev/cmd/go
    # https://pkg.go.dev/cmd/link

    unset GO_BUILD_ARGS
    unset GO_BUILD_ARGV_V
    unset GO_BUILD_ARGV_X
    unset GO_BUILD_ARGV_O
    unset GO_BUILD_ARGV_MOD
    unset GO_BUILD_ARGV_TAGS
    unset GO_BUILD_ARGV_LDFLAGS

    unset GO_BUILD_ARGS_EXTRA

    while [ -n "$1" ]
    do
        case $1 in
            -v) shift ; GO_BUILD_ARGV_V='-v' ;;
            -x) shift ; GO_BUILD_ARGV_X='-x' ;;
            -o) shift ; GO_BUILD_ARGV_O="$1" ; shift ;;
            -X) shift
                if [ -z "$GO_BUILD_ARGV_LDFLAGS" ] ; then
                    GO_BUILD_ARGV_LDFLAGS="-X $1"
                else
                    GO_BUILD_ARGV_LDFLAGS="$GO_BUILD_ARGV_LDFLAGS -X $1"
                fi
                shift
                ;;
            -ldflags)
                shift
                if [ -z "$GO_BUILD_ARGV_LDFLAGS" ] ; then
                    GO_BUILD_ARGV_LDFLAGS="$1"
                else
                    GO_BUILD_ARGV_LDFLAGS="$1 $GO_BUILD_ARGV_LDFLAGS"
                fi
                shift
                ;;
            *)  GO_BUILD_ARGS_EXTRA="$GO_BUILD_ARGS_EXTRA $1" ; shift
        esac
    done

    GO_BUILD_ARGS='-trimpath'

    if [ -z "$GO_BUILD_ARGV_V" ] ; then
        if [ "$VERBOSE_GO" = 1 ] ; then
            GO_BUILD_ARGS="$GO_BUILD_ARGS -v"
        fi
    else
        GO_BUILD_ARGS="$GO_BUILD_ARGS -v"
    fi

    if [ -z "$GO_BUILD_ARGV_X" ] ; then
        if [ "$DEBUG_GO" = 1 ] ; then
            GO_BUILD_ARGS="$GO_BUILD_ARGS -x"
        fi
    else
        GO_BUILD_ARGS="$GO_BUILD_ARGS -x"
    fi

    if [ "$PROFILE" = release ] ; then
        GO_BUILD_ARGV_LDFLAGS="$GO_BUILD_ARGV_LDFLAGS -s -w"
    fi

    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] && [ "$CGO_ENABLED" = 1 ] ; then
        GO_BUILD_ARGV_LDFLAGS="$GO_BUILD_ARGV_LDFLAGS -linkmode external \"-extldflags=-static\""
    fi

    GO_BUILD_ARGS="$GO_BUILD_ARGS -ldflags '$GO_BUILD_ARGV_LDFLAGS'"

    if [ -z "$GO_BUILD_ARGV_O" ] ; then
        GO_BUILD_ARGS="$GO_BUILD_ARGS -o $PACKAGE_BCACHED_DIR/"
    else
        GO_BUILD_ARGS="$GO_BUILD_ARGS -o $PACKAGE_BCACHED_DIR/$GO_BUILD_ARGV_O"
    fi

    GO_BUILD_ARGS="$GO_BUILD_ARGS $GO_BUILD_ARGS_EXTRA"

    # shellcheck disable=SC2086
    run go build $GO_BUILD_ARGS

    for item in $(ls "$PACKAGE_BCACHED_DIR")
    do
        case $item in
            *.a)  run install_libs "$PACKAGE_BCACHED_DIR/$item" ;;
            *.so) run install_libs "$PACKAGE_BCACHED_DIR/$item" ;;
            *)    run install_bins "$PACKAGE_BCACHED_DIR/$item" ;;
        esac
    done
}

# }}}
##############################################################################
# {{{ __setup_sysroot

__setup_sysroot_dragonflybsd() {
    FILENAME="$TARGET_PLATFORM_SPEC.txz"

    wfetch "https://github.com/leleliu008/test/releases/download/2023.10.08/dragonflybsd-6.4-x86_64-sysroot.tar.xz" -o "$FILENAME"

    run bsdtar xvf "$FILENAME" -C "$TARGET_PLATFORM_SPEC" --strip-components=1
}

__setup_sysroot_freebsd() {
    FILENAME="$TARGET_PLATFORM_SPEC.txz"

    # https://archive.freebsd.org/old-releases/
    wfetch "https://archive.freebsd.org/old-releases/$TARGET_PLATFORM_ARCH/$TARGET_PLATFORM_VERS-RELEASE/base.txz" -o "$FILENAME"

    run bsdtar xvf "$FILENAME" -C "$TARGET_PLATFORM_SPEC"

    #run rm -rf "$TARGET_PLATFORM_SPEC/bin"
    #run rm -rf "$TARGET_PLATFORM_SPEC/usr/bin"
    #run rm -rf "$TARGET_PLATFORM_SPEC/sbin"
    #run rm -rf "$TARGET_PLATFORM_SPEC/usr/sbin"

    rm "$TARGET_PLATFORM_SPEC/usr/lib/libgcc.a"

    printf '%s\n' 'INPUT(-lc++)'                  > "$TARGET_PLATFORM_SPEC/usr/lib/libstdc++.a"
    printf '%s\n' 'INPUT(-lcompiler_rt -lgcc_eh)' > "$TARGET_PLATFORM_SPEC/usr/lib/libgcc.a"
    printf '%s\n' 'INPUT(-lcompiler_rt -lgcc_eh)' > "$TARGET_PLATFORM_SPEC/usr/lib/libgcc_s.a"
}

__setup_sysroot_openbsd() {
    TARGET_PLATFORM_VERS_MAJOR="$(printf '%s\n' "$TARGET_PLATFORM_VERS" | cut -d. -f1)"
    TARGET_PLATFORM_VERS_MINOR="$(printf '%s\n' "$TARGET_PLATFORM_VERS" | cut -d. -f2)"

    for item in base comp
    do
        FILENAME="$TARGET_PLATFORM_SPEC-$item.tgz"
        URL="https://cdn.openbsd.org/pub/OpenBSD/$TARGET_PLATFORM_VERS/$TARGET_PLATFORM_ARCH/$item$TARGET_PLATFORM_VERS_MAJOR$TARGET_PLATFORM_VERS_MINOR.tgz"
        wfetch "$URL" -o "$FILENAME"
        run bsdtar xvf   "$FILENAME" -C "$TARGET_PLATFORM_SPEC"
    done

    cd "$TARGET_PLATFORM_SPEC/usr/lib"

    # https://github.com/mesonbuild/meson/issues/5390
    printf '%s\n' 'INPUT(-lc)'                    > libdl.a
    printf '%s\n' 'INPUT(-lc)'                    > librt.a
    printf '%s\n' 'INPUT(-lc)'                    > libcrypt.a
    printf '%s\n' 'INPUT(-lc++)'                  > libstdc++.a
    printf '%s\n' 'INPUT(-lcompiler_rt -lc++abi)' > libgcc.a
    printf '%s\n' 'INPUT(-lcompiler_rt -lc++abi)' > libgcc_s.a

    for f in lib*.so.*
    do
        ln -s "$f" "${f%.so.*}.so"
    done

    cd -
}

__setup_sysroot_netbsd() {
    case $TARGET_PLATFORM_VERS in
        [1-8].*)  NETBSD_DOWNLOAD_SERVER='https://archive.netbsd.org/pub/NetBSD-archive' ;;
        9.[0-2])  NETBSD_DOWNLOAD_SERVER='https://archive.netbsd.org/pub/NetBSD-archive' ;;
        *)        NETBSD_DOWNLOAD_SERVER='https://ftp.netbsd.org/pub/NetBSD' ;;
    esac

    for item in base comp
    do
        FILENAME="$TARGET_PLATFORM_SPEC-$item.txz"
        URL="$NETBSD_DOWNLOAD_SERVER/NetBSD-$TARGET_PLATFORM_VERS/amd64/binary/sets/$item.tar.xz"
        wfetch "$URL" -o "$FILENAME"
        run bsdtar xvf "$FILENAME" -C "$TARGET_PLATFORM_SPEC"
    done

    cd "$TARGET_PLATFORM_SPEC/usr/lib"

    #run rm -rf "$TARGET_PLATFORM_SPEC/bin"
    #run rm -rf "$TARGET_PLATFORM_SPEC/usr/bin"
    #run rm -rf "$TARGET_PLATFORM_SPEC/sbin"
    #run rm -rf "$TARGET_PLATFORM_SPEC/usr/sbin"

    printf '%s\n' 'INPUT(-lstdc++)' > libc++.a
    printf '%s\n' 'INPUT(-lc)'      > libdl.a
    printf '%s\n' 'INPUT(-lgcc_eh)' > libgcc_s.a

    cd -
}

__setup_sysroot_linux() {
    if [ "$TARGET_PLATFORM_VERS" = musl ] ; then
        FILENAME="$TARGET_PLATFORM_SPEC-libc.txz"

        wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/musl-libc-1.2.3-linux-x86_64-musl.tar.xz' -o "$FILENAME"

        run bsdtar xvf "$FILENAME" -C "$TARGET_PLATFORM_SPEC" --strip-components=1
    fi
}

__setup_sysroot() {
    run install -d "$PPKG_SYSROOT"
    run cd         "$PPKG_SYSROOT"

    run install -d "$TARGET_PLATFORM_SPEC"

    __setup_sysroot_$TARGET_PLATFORM_NAME

    run touch "$TARGET_PLATFORM_SPEC/ok"
}

# }}}
##############################################################################
# {{{ inspect_package_spec

# inspect_package_spec <PACKAGE-NAME|PACKAGE-SPEC> [DEFAULT-TARGET]
  inspect_package_spec() {
    case $1 in
        '') abort 1 "package-name or package-spec is unspecified."
            ;;
        */*)
            PACKAGE_NAME="${1##*/}"

            if [ -z "$PACKAGE_NAME" ] ; then
                abort 1 "invalid package-spec: $1\npackage-name is unspecified."
            elif printf '%s\n' "$PACKAGE_NAME" | grep -q -E '^[A-Za-z0-9+-._@]{1,50}$' ; then
                :
            else
                abort 1 "invalid package-spec: $1\npackage-name does not match pattern ^[A-Za-z0-9+-._@]{1,50}$"
            fi

            TARGET_PLATFORM_SPEC="${1%/*}"

            TARGET_PLATFORM_NAME=
            TARGET_PLATFORM_VERS=
            TARGET_PLATFORM_ARCH=

            TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
            TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
            TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

            if [ -z "$TARGET_PLATFORM_NAME" ] ; then
                abort 1 "invalid package-spec: $1, platform-name is unspecified."
            fi

            if [ -z "$TARGET_PLATFORM_VERS" ] ; then
                abort 1 "invalid package-spec: $1, platform-arch is unspecified."
            fi

            if [ -z "$TARGET_PLATFORM_ARCH" ] ; then
                abort 1 "invalid package-spec: $1, platform-arch is unspecified."
            fi

            case $TARGET_PLATFORM_NAME in
                linux)
                    case $TARGET_PLATFORM_VERS in
                        glibc|musl) ;;
                        *)  abort 1 "invalid package-spec: $1, unrecognized libc: $TARGET_PLATFORM_VERS"
                    esac
                    ;;
                macos)
                    case $TARGET_PLATFORM_ARCH in
                        x86_64|arm64) ;;
                        *)  abort 1 "invalid package-spec: $1, unsupported arch: $TARGET_PLATFORM_ARCH"
                    esac
                    ;;
                freebsd)
                    case $TARGET_PLATFORM_ARCH in
                        x86_64) TARGET_PLATFORM_ARCH='amd64'
                    esac
                    ;;
                openbsd)
                    case $TARGET_PLATFORM_ARCH in
                        x86_64) TARGET_PLATFORM_ARCH='amd64'
                    esac
                    ;;
                netbsd)
                    case $TARGET_PLATFORM_ARCH in
                        x86_64) TARGET_PLATFORM_ARCH='amd64'
                    esac
                    ;;
                dragonflybsd)
                    case $TARGET_PLATFORM_ARCH in
                        amd64) TARGET_PLATFORM_ARCH='x86_64'
                    esac
                    ;;
                *)  abort 1 "invalid package-spec: $1, unsupported platform: $TARGET_PLATFORM_NAME"
            esac

            PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME"
            printf '%s\n' "$PACKAGE_SPEC"
            ;;
        *)  if printf '%s\n' "$1" | grep -q -E '^[A-Za-z0-9+-._@]{1,50}$' ; then
                case $2 in
                    '') ;;
                    *-*-*-*)
                        abort 1 "you have specified --target=$2 , but it is an invalid target."
                        ;;
                    *-*-*)
                        TARGET_PLATFORM_NAME=
                        TARGET_PLATFORM_VERS=
                        TARGET_PLATFORM_ARCH=

                        TARGET_PLATFORM_NAME="$(printf '%s\n' "$2" | cut -d- -f1)"
                        TARGET_PLATFORM_VERS="$(printf '%s\n' "$2" | cut -d- -f2)"
                        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$2" | cut -d- -f3)"

                        if [ -z "$TARGET_PLATFORM_NAME" ] ; then
                            abort 1 "you have specified --target=$2 , but it is an invalid target."
                        fi

                        if [ -z "$TARGET_PLATFORM_VERS" ] ; then
                            abort 1 "you have specified --target=$2 , but it is an invalid target."
                        fi

                        if [ -z "$TARGET_PLATFORM_ARCH" ] ; then
                            abort 1 "you have specified --target=$2 , but it is an invalid target."
                        fi

                        case $TARGET_PLATFORM_NAME in
                            linux)
                                case $TARGET_PLATFORM_VERS in
                                    glibc|musl) ;;
                                    *)  abort 1 "you have specified --target=$2 , but it is an invalid target, unrecognized libc: $TARGET_PLATFORM_VERS"
                                esac
                                ;;
                            macos)
                                case $TARGET_PLATFORM_ARCH in
                                    x86_64|arm64) ;;
                                    *)  abort 1 "you have specified --target=$2 , but it is an invalid target, unsupported arch: $TARGET_PLATFORM_ARCH"
                                esac
                                ;;
                            freebsd)
                                case $TARGET_PLATFORM_ARCH in
                                    x86_64) TARGET_PLATFORM_ARCH='amd64'
                                esac
                                ;;
                            openbsd)
                                case $TARGET_PLATFORM_ARCH in
                                    x86_64) TARGET_PLATFORM_ARCH='amd64'
                                esac
                                ;;
                            netbsd)
                                case $TARGET_PLATFORM_ARCH in
                                    x86_64) TARGET_PLATFORM_ARCH='amd64'
                                esac
                                ;;
                            dragonflybsd)
                                case $TARGET_PLATFORM_ARCH in
                                    amd64) TARGET_PLATFORM_ARCH='x86_64'
                                esac
                                ;;
                            *)  abort 1 "you have specified --target=$2 , but it is an invalid target, unsupported platform: $TARGET_PLATFORM_NAME"
                        esac

                        TARGET_PLATFORM_SPEC="$TARGET_PLATFORM_NAME-$TARGET_PLATFORM_VERS-$TARGET_PLATFORM_ARCH"
                        PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$1"

                        note "$1 will be treated as a package-name, and it will be expanded to $PACKAGE_SPEC"
                        printf '%s\n' "$PACKAGE_SPEC"
                        return 0
                        ;;
                    *)  abort 1 "you have specified --target=$2 , but it is an invalid target."
                esac

                case $PPKG_DEFAULT_TARGET in
                    '')
                        TARGET_PLATFORM_NAME="$NATIVE_PLATFORM_TYPE"
                        TARGET_PLATFORM_ARCH="$NATIVE_PLATFORM_ARCH"

                        if [ "$NATIVE_PLATFORM_TYPE" = linux ] ; then
                            TARGET_PLATFORM_VERS="$NATIVE_PLATFORM_LIBC"
                        else
                            TARGET_PLATFORM_VERS="$NATIVE_PLATFORM_VERS"
                        fi

                        TARGET_PLATFORM_SPEC="$TARGET_PLATFORM_NAME-$TARGET_PLATFORM_VERS-$TARGET_PLATFORM_ARCH"

                        PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$1"
                        ;;
                    *-*-*-*)
                        abort 1 "you have set PPKG_DEFAULT_TARGET=$PPKG_DEFAULT_TARGET , but it is an invalid target."
                        ;;
                    *-*-*)
                        TARGET_PLATFORM_NAME=
                        TARGET_PLATFORM_VERS=
                        TARGET_PLATFORM_ARCH=

                        TARGET_PLATFORM_NAME="$(printf '%s\n' "$PPKG_DEFAULT_TARGET" | cut -d- -f1)"
                        TARGET_PLATFORM_VERS="$(printf '%s\n' "$PPKG_DEFAULT_TARGET" | cut -d- -f2)"
                        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$PPKG_DEFAULT_TARGET" | cut -d- -f3)"

                        if [ -z "$TARGET_PLATFORM_NAME" ] ; then
                            abort 1 "you have set PPKG_DEFAULT_TARGET=$PPKG_DEFAULT_TARGET , but it is an invalid package spec."
                        fi

                        if [ -z "$TARGET_PLATFORM_VERS" ] ; then
                            abort 1 "you have set PPKG_DEFAULT_TARGET=$PPKG_DEFAULT_TARGET , but it is an invalid target."
                        fi

                        if [ -z "$TARGET_PLATFORM_ARCH" ] ; then
                            abort 1 "you have set PPKG_DEFAULT_TARGET=$PPKG_DEFAULT_TARGET , but it is an invalid target."
                        fi

                        case $TARGET_PLATFORM_NAME in
                            linux)
                                case $TARGET_PLATFORM_VERS in
                                    glibc|musl) ;;
                                    *)  abort 1 "you have set PPKG_DEFAULT_TARGET=$PPKG_DEFAULT_TARGET , but it is an invalid target, unrecognized libc: $TARGET_PLATFORM_VERS"
                                esac
                                ;;
                            macos)
                                case $TARGET_PLATFORM_ARCH in
                                    x86_64|arm64) ;;
                                    *)  abort 1 "you have set PPKG_DEFAULT_TARGET=$PPKG_DEFAULT_TARGET , but it is an invalid target, unsupported arch: $TARGET_PLATFORM_ARCH"
                                esac
                                ;;
                            freebsd)
                                case $TARGET_PLATFORM_ARCH in
                                    x86_64) TARGET_PLATFORM_ARCH='amd64'
                                esac
                                ;;
                            openbsd)
                                case $TARGET_PLATFORM_ARCH in
                                    x86_64) TARGET_PLATFORM_ARCH='amd64'
                                esac
                                ;;
                            netbsd)
                                case $TARGET_PLATFORM_ARCH in
                                    x86_64) TARGET_PLATFORM_ARCH='amd64'
                                esac
                                ;;
                            dragonflybsd)
                                case $TARGET_PLATFORM_ARCH in
                                    amd64) TARGET_PLATFORM_ARCH='x86_64'
                                esac
                                ;;
                            *)  abort 1 "you have set PPKG_DEFAULT_TARGET=$PPKG_DEFAULT_TARGET , but it is an invalid target, unsupported platform: $TARGET_PLATFORM_NAME"
                        esac

                        TARGET_PLATFORM_SPEC="$TARGET_PLATFORM_NAME-$TARGET_PLATFORM_VERS-$TARGET_PLATFORM_ARCH"
                        PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$1"
                        ;;
                    *) abort 1 "you have set PPKG_DEFAULT_TARGET=$PPKG_DEFAULT_TARGET , but it is an invalid target."
                esac

                note "$1 will be treated as a package-name, and it will be expanded to $PACKAGE_SPEC"
                printf '%s\n' "$PACKAGE_SPEC"
            else
                abort 1 "invalid package-name: $1\npackage-name does not match pattern ^[A-Za-z0-9+-._@]{1,50}$"
            fi
    esac
}

# }}}
##############################################################################
# {{{ __initialize_environment_variables

__initialize_environment_variables() {
    unset      CC_FOR_BUILD
    unset    OBJC_FOR_BUILD
    unset     CXX_FOR_BUILD
    unset     CPP_FOR_BUILD
    unset      AS_FOR_BUILD
    unset      AR_FOR_BUILD
    unset  RANLIB_FOR_BUILD
    unset      LD_FOR_BUILD
    unset      NM_FOR_BUILD
    unset    SIZE_FOR_BUILD
    unset   STRIP_FOR_BUILD
    unset STRINGS_FOR_BUILD
    unset OBJDUMP_FOR_BUILD
    unset OBJCOPY_FOR_BUILD
    unset READELF_FOR_BUILD
    unset SYSROOT_FOR_BUILD

    #####################################################################

    # https://www.gnu.org/software/make/manual/html_node/Environment.html
    # https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html

    unset LIBS

    # https://mesonbuild.com/Reference-tables.html#compiler-and-linker-flag-environment-variables
    unset VALAFLAGS
    unset RUSTFLAGS

    # autoreconf --help
    unset AUTOCONF
    unset AUTOHEADER
    unset AUTOM4TE
    unset AUTOMAKE
    unset AUTOPOINT
    unset ACLOCAL
    unset GTKDOCIZE
    unset INTLTOOLIZE
    unset LIBTOOLIZE
    unset M4
    unset MAKE
    unset autom4te_perllibdir
    unset trailer_m4

    # https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html
    # https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
    # https://clang.llvm.org/docs/CommandGuide/clang.html#environment
    unset CPATH
    unset C_INCLUDE_PATH
    unset CPLUS_INCLUDE_PATH
    unset OBJC_INCLUDE_PATH
    unset OBJCPLUS_INCLUDE_PATH
    unset DEPENDENCIES_OUTPUT
    unset SUNPRO_DEPENDENCIES
    unset SOURCE_DATE_EPOCH
    unset GCC_EXEC_PREFIX
    unset COMPILER_PATH
    unset LIBRARY_PATH

    # https://cmake.org/cmake/help/latest/envvar/MACOSX_DEPLOYMENT_TARGET.html
    # https://clang.llvm.org/docs/CommandGuide/clang.html#environment
    unset   MACOSX_DEPLOYMENT_TARGET
    unset IPHONEOS_DEPLOYMENT_TARGET
    unset  WATCHOS_DEPLOYMENT_TARGET

    # https://stackoverflow.com/questions/18476490/what-is-purpose-of-target-arch-variable-in-makefiles
    unset TARGET_ARCH

    # https://keith.github.io/xcode-man-pages/xcrun.1.html
    # https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_SYSROOT.html
    unset SDKROOT

    unset SYSROOT

    # https://cmake.org/cmake/help/latest/envvar/DESTDIR.html
    # https://www.gnu.org/prep/standards/html_node/DESTDIR.html
    # https://mensinda.github.io/meson/Installing.html#destdir-support
    unset DESTDIR

    #######################################################################

    # https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html
    unset CMAKE_APPBUNDLE_PATH
    unset CMAKE_FRAMEWORK_PATH
    unset CMAKE_PROGRAM_PATH
    unset CMAKE_INCLUDE_PATH
    unset CMAKE_LIBRARY_PATH
    unset CMAKE_PREFIX_PATH
    unset CMAKE_MAXIMUM_RECURSION_DEPTH
    unset CMAKE_APPLE_SILICON_PROCESSOR
    unset CMAKE_BUILD_PARALLEL_LEVEL
    unset CMAKE_BUILD_TYPE
    unset CMAKE_CONFIGURATION_TYPES
    unset CMAKE_CONFIG_TYPE
    unset CMAKE_EXPORT_COMPILE_COMMANDS
    unset CMAKE_GENERATOR
    unset CMAKE_GENERATOR_INSTANCE
    unset CMAKE_GENERATOR_PLATFORM
    unset CMAKE_GENERATOR_TOOLSET
    unset CMAKE_INSTALL_MODE
    unset CMAKE_C_COMPILER_LAUNCHER
    unset CMAKE_C_LINKER_LAUNCHER
    unset CMAKE_CXX_COMPILER_LAUNCHER
    unset CMAKE_CXX_LINKER_LAUNCHER
    unset CMAKE_MSVCIDE_RUN_PATH
    unset CMAKE_NO_VERBOSE
    unset CMAKE_OSX_ARCHITECTURES
    unset CMAKE_TOOLCHAIN_FILE
    unset CTEST_INTERACTIVE_DEBUG_MODE
    unset CTEST_OUTPUT_ON_FAILURE
    unset CTEST_PARALLEL_LEVEL
    unset CTEST_PROGRESS_OUTPUT
    unset CTEST_USE_LAUNCHERS_DEFAULT
    unset DASHBOARD_TEST_FROM_CTEST
    unset VERBOSE

    # https://cmake.org/cmake/help/latest/envvar/CMAKE_BUILD_PARALLEL_LEVEL.html
    export CMAKE_BUILD_PARALLEL_LEVEL="$BUILD_NJOBS"

    # https://cmake.org/cmake/help/latest/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.html
    if [ "$EXPORT_COMPILE_COMMANDS_JSON" = 1 ] ; then
        export CMAKE_EXPORT_COMPILE_COMMANDS=ON
    else
        export CMAKE_EXPORT_COMPILE_COMMANDS=OFF
    fi

    case $PROFILE in
        debug)   CMAKE_BUILD_TYPE=Debug   ;;
        release) CMAKE_BUILD_TYPE=Release ;;
    esac

    if [ "$VERBOSE_CMAKE" = 1 ] ; then
        CMAKE_VERBOSE_MAKEFILE=ON
        CMAKE_COLOR_MAKEFILE=ON
    else
        CMAKE_VERBOSE_MAKEFILE=OFF
        CMAKE_COLOR_MAKEFILE=OFF
    fi

    # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_DEBUG_MODE.html
    if [ "$DEBUG_CMAKE" = 1 ] ; then
        CMAKE_FIND_DEBUG_MODE=ON
    else
        CMAKE_FIND_DEBUG_MODE=OFF
    fi

    ########################################################

    if [ "$NATIVE_PLATFORM_KIND" = 'darwin' ] ; then
             CC_FOR_BUILD="$(xcrun --sdk macosx --find clang)"
           OBJC_FOR_BUILD="$(xcrun --sdk macosx --find clang)"
            CXX_FOR_BUILD="$(xcrun --sdk macosx --find clang++)"
             AS_FOR_BUILD="$(xcrun --sdk macosx --find as)"
             AR_FOR_BUILD="$(xcrun --sdk macosx --find ar)"
         RANLIB_FOR_BUILD="$(xcrun --sdk macosx --find ranlib)"
             LD_FOR_BUILD="$(xcrun --sdk macosx --find ld)"
             NM_FOR_BUILD="$(xcrun --sdk macosx --find nm)"
           SIZE_FOR_BUILD="$(xcrun --sdk macosx --find size)"
          STRIP_FOR_BUILD="$(xcrun --sdk macosx --find strip)"
        STRINGS_FOR_BUILD="$(xcrun --sdk macosx --find strings)"
        OBJDUMP_FOR_BUILD="$(xcrun --sdk macosx --find objdump)"
        SYSROOT_FOR_BUILD="$(xcrun --sdk macosx --show-sdk-path)"
    else
             CC_FOR_BUILD="$(command -v gcc || command -v clang   || command -v cc)"   || abort 1 "C Compiler for native build not found."
           OBJC_FOR_BUILD="$(command -v gcc || command -v clang   || command -v objc)" || abort 1 "OBJC Compiler for native build not found."
            CXX_FOR_BUILD="$(command -v g++ || command -v clang++ || command -v c++)"  || abort 1 "C++ Compiler for native build not found."
             AS_FOR_BUILD="$(command -v as)"      || abort 1 "command not found: as"
             AR_FOR_BUILD="$(command -v ar)"      || abort 1 "command not found: ar"
         RANLIB_FOR_BUILD="$(command -v ranlib)"  || abort 1 "command not found: ranlib"
             LD_FOR_BUILD="$(command -v ld)"      || abort 1 "command not found: ld"
             NM_FOR_BUILD="$(command -v nm)"      || abort 1 "command not found: nm"
           SIZE_FOR_BUILD="$(command -v size)"    || abort 1 "command not found: size"
          STRIP_FOR_BUILD="$(command -v strip)"   || abort 1 "command not found: strip"
        STRINGS_FOR_BUILD="$(command -v strings)" || abort 1 "command not found: strings"
        OBJDUMP_FOR_BUILD="$(command -v objdump)" || abort 1 "command not found: objdump"
        OBJCOPY_FOR_BUILD="$(command -v objcopy)" || abort 1 "command not found: objcopy"
        READELF_FOR_BUILD="$(command -v readelf)" || abort 1 "command not found: readelf"
    fi

    export PROXIED_NATIVE_CC="$CC_FOR_BUILD"
    export PROXIED_NATIVE_CXX="$CXX_FOR_BUILD"
    export PROXIED_NATIVE_OBJC="$OBJC_FOR_BUILD"

     CC_FOR_BUILD="$PPKG_CORE_DIR/wrapper-native-cc"
   OBJC_FOR_BUILD="$PPKG_CORE_DIR/wrapper-native-objc"
    CXX_FOR_BUILD="$PPKG_CORE_DIR/wrapper-native-c++"
    CPP_FOR_BUILD="$CC_FOR_BUILD -E"

    ########################################################

    if [ "$NATIVE_PLATFORM_KIND" = 'darwin' ] ; then
          CFLAGS_FOR_BUILD="-isysroot $SYSROOT_FOR_BUILD -mmacosx-version-min=$NATIVE_PLATFORM_VERS -arch $NATIVE_PLATFORM_ARCH -Qunused-arguments"
       OBJCFLAGS_FOR_BUILD="-isysroot $SYSROOT_FOR_BUILD -mmacosx-version-min=$NATIVE_PLATFORM_VERS -arch $NATIVE_PLATFORM_ARCH -Qunused-arguments"
        CXXFLAGS_FOR_BUILD="-isysroot $SYSROOT_FOR_BUILD -mmacosx-version-min=$NATIVE_PLATFORM_VERS -arch $NATIVE_PLATFORM_ARCH -Qunused-arguments"
        CPPFLAGS_FOR_BUILD="-isysroot $SYSROOT_FOR_BUILD -Qunused-arguments"
         LDFLAGS_FOR_BUILD="-isysroot $SYSROOT_FOR_BUILD -mmacosx-version-min=$NATIVE_PLATFORM_VERS -arch $NATIVE_PLATFORM_ARCH"
    else
          CFLAGS_FOR_BUILD="-fPIC -fno-common"
       OBJCFLAGS_FOR_BUILD="-fPIC -fno-common"
        CXXFLAGS_FOR_BUILD="-fPIC -fno-common"
        CPPFLAGS_FOR_BUILD=
        # https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
         LDFLAGS_FOR_BUILD="-Wl,--as-needed -Wl,-z,muldefs -Wl,--allow-multiple-definition"
    fi

    if [ "$DEBUG_CC" = 1 ] ; then
          CFLAGS_FOR_BUILD="$CFLAGS_FOR_BUILD -v"
        CXXFLAGS_FOR_BUILD="$CXXFLAGS_FOR_BUILD -v"
       OBJCFLAGS_FOR_BUILD="$OBJCFLAGS_FOR_BUILD -v"
    fi

    if [ "$DEBUG_LD" = 1 ] ; then
         LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -Wl,-v"
    fi

    if [ "$PROFILE" = release ] ; then
          CFLAGS_FOR_BUILD="$CFLAGS_FOR_BUILD -Os"
        CXXFLAGS_FOR_BUILD="$CXXFLAGS_FOR_BUILD -Os"
       OBJCFLAGS_FOR_BUILD="$OBJCFLAGS_FOR_BUILD -Os"
         LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -Wl,-S"
    fi

    case $NATIVE_PLATFORM_KIND in
        netbsd)  LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -lpthread" ;;
        openbsd) LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -lpthread" ;;
    esac

    LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -L$PPKG_CORE_DIR/lib"

    ########################################################

    for TOOL in CC OBJC CXX CPP AS AR RANLIB LD NM STRIP SIZE STRINGS OBJDUMP OBJCOPY READELF SYSROOT CFLAGS OBJCFLAGS CXXFLAGS CPPFLAGS LDFLAGS
    do
        export "${TOOL}_FOR_BUILD"
        eval export "$TOOL=\"\$${TOOL}_FOR_BUILD\""
    done

    ########################################################

    if [ "$DEBUG_CC" = 1 ] ; then
        # used by wrapper-target-*
        export PPKG_VERBOSE=1
    else
        unset  PPKG_VERBOSE
    fi

    ########################################################

    WRAPPER_TARGET_CC="$PPKG_CORE_DIR/wrapper-target-cc"
    WRAPPER_TARGET_CXX="$PPKG_CORE_DIR/wrapper-target-c++"
    WRAPPER_TARGET_OBJC="$PPKG_CORE_DIR/wrapper-target-cc"
}

# }}}
##############################################################################
# {{{ __inspect_install_arguments

__inspect_install_arguments() {
    LOG_LEVEL_QUIET=0
    LOG_LEVEL_NORMAL=1
    LOG_LEVEL_VERBOSE=2
    LOG_LEVEL_VERY_VERBOSE=3

    unset PROFILE

    unset LOG_LEVEL

    unset BUILD_NJOBS

    unset ENABLE_LTO

    unset ENABLE_STRIP

    unset ENABLE_CCACHE

    unset REQUEST_TO_KEEP_SESSION_DIR

    unset REQUEST_TO_UPGRADE_IF_POSSIBLE

    unset REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON

    unset REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE

    unset SPECIFIED_FORMULA_SEARCH_DIRS

    unset SPECIFIED_PACKAGE_LIST

    unset SPECIFIED_TARGET

    unset DUMP_ENV
    unset DUMP_HTTP
    unset DUMP_UPPM
    unset DUMP_TOOLCHAIN
    unset DUMP_SED
    unset DUMP_FORMULA

    unset VERBOSE_GO
    unset VERBOSE_CARGO
    unset VERBOSE_CABAL
    unset VERBOSE_MESON
    unset VERBOSE_NINJA
    unset VERBOSE_GMAKE
    unset VERBOSE_CMAKE
    unset VERBOSE_XMAKE

    unset DEBUG_CC
    unset DEBUG_LD
    unset DEBUG_GO
    unset DEBUG_CARGO
    unset DEBUG_CABAL
    unset DEBUG_GMAKE
    unset DEBUG_CMAKE
    unset DEBUG_XMAKE
    unset DEBUG_PKG_CONFIG

    while [ -n "$1" ]
    do
        case $1 in
            -q) LOG_LEVEL=0 ;;
            -v) LOG_LEVEL=2

                DUMP_ENV=1
                DUMP_HTTP=1
                DUMP_UPPM=1
                DUMP_TOOLCHAIN=1
                DUMP_SED=1
                DUMP_FORMULA=1

                VERBOSE_GO=1
                VERBOSE_CARGO=1
                VERBOSE_CABAL=1
                VERBOSE_MESON=1
                VERBOSE_NINJA=1
                VERBOSE_GMAKE=1
                VERBOSE_CMAKE=1
                VERBOSE_XMAKE=1
                ;;
            -x) LOG_LEVEL=3

                DUMP_ENV=1
                DUMP_HTTP=1
                DUMP_UPPM=1
                DUMP_TOOLCHAIN=1
                DUMP_SED=1
                DUMP_FORMULA=1

                VERBOSE_MESON=1
                VERBOSE_NINJA=1
                VERBOSE_GMAKE=1
                VERBOSE_CMAKE=1
                VERBOSE_XMAKE=1

                DEBUG_CC=1
                DEBUG_LD=1
                DEBUG_GO=1
                DEBUG_CARGO=1
                DEBUG_CABAL=1
                DEBUG_GMAKE=1
                DEBUG_CMAKE=1
                DEBUG_XMAKE=1
                DEBUG_PKG_CONFIG=1
                ;;
            -v-env)
                DUMP_ENV=1
                ;;
            -v-http)
                DUMP_HTTP=1
                ;;
            -v-uppm)
                DUMP_UPPM=1
                ;;
            -v-toolchain)
                DUMP_TOOLCHAIN=1
                ;;
            -v-formula)
                DUMP_FORMULA=1
                ;;
            -v-go)
                VERBOSE_GO=1
                ;;
            -v-cargo)
                VERBOSE_CARGO=1
                ;;
            -v-cabal)
                VERBOSE_CABAL=1
                ;;
            -v-meson)
                VERBOSE_MESON=1
                ;;
            -v-ninja)
                VERBOSE_NINJA=1
                ;;
            -v-gmake)
                VERBOSE_GMAKE=1
                ;;
            -v-cmake)
                VERBOSE_CMAKE=1
                ;;
            -v-xmake)
                VERBOSE_XMAKE=1
                ;;
            -x-sh)
                set -x
                ;;
            -x-cc)
                DEBUG_CC=1
                ;;
            -x-ld)
                DEBUG_LD=1
                ;;
            -x-go)
                DEBUG_GO=1
                ;;
            -x-cargo)
                DEBUG_CARGO=1
                ;;
            -x-cabal)
                DEBUG_CABAL=1
                ;;
            -x-gmake)
                DEBUG_GMAKE=1
                ;;
            -x-cmake)
                DEBUG_CMAKE=1
                ;;
            -x-xmake)
                DEBUG_XMAKE=1
                ;;
            -x-pkg-config)
                DEBUG_PKG_CONFIG=1
                ;;

            --disable-ccache)
                ENABLE_CCACHE=0
                ;;
            --enable-lto)
                ENABLE_LTO=1
                ;;
            --enable-strip)
                ENABLE_STRIP=all
                ;;
            --enable-strip=*)
                ENABLE_STRIP="${1#*=}"
                case $ENABLE_STRIP in
                    no|all|debug|unneeded) ;;
                    *)  abort 1 "--strip=<VALUE>, VALUE should be one of no, all, debug, unneeded"
                esac
                ;;
            --target=*)
                SPECIFIED_TARGET="${1#*=}"
                ;;
            --profile=*)
                PROFILE="${1#*=}"
                ;;
            --static)
                REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=1
                ;;
            -j) shift
                isInteger "$1" || abort 1 "-j <N>, <N> should be an integer."
                BUILD_NJOBS="$1"
                ;;
            -I) shift
                [ -z "$1" ] && abort 1 "-I <FORMULA-SEARCH-DIR> , <FORMULA-SEARCH-DIR> is unspecified."
                [ -e "$1" ] || abort 1 "'$1' was expected to be exist, but it was not."
                [ -d "$1" ] || abort 1 "'$1' was expected to be a directory, but it was not."
                FORMULA_SEARCH_DIR="$(realpath "$1")"
                SPECIFIED_FORMULA_SEARCH_DIRS="$SPECIFIED_FORMULA_SEARCH_DIRS:$FORMULA_SEARCH_DIR"
                ;;
            -K) REQUEST_TO_KEEP_SESSION_DIR=1 ;;
            -U) REQUEST_TO_UPGRADE_IF_POSSIBLE=1 ;;
            -E) REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON=1 ;;

            -*) abort 1 "unrecognized option: $1"
                ;;
            *)  SPECIFIED_PACKAGE_LIST="$SPECIFIED_PACKAGE_LIST $1"
        esac
        shift
    done

    #########################################################################################

    if [ -z "$PPKG_FORMULA_SEARCH_DIRS" ] ; then
        PPKG_FORMULA_SEARCH_DIRS="${SPECIFIED_FORMULA_SEARCH_DIRS#:}"
    else
        PPKG_FORMULA_SEARCH_DIRS="${SPECIFIED_FORMULA_SEARCH_DIRS#:}:$PPKG_FORMULA_SEARCH_DIRS"
    fi

    #########################################################################################

    unset SPECIFIED_PACKAGE_SPEC_LIST

    for PACKAGE in $SPECIFIED_PACKAGE_LIST
    do
        SPECIFIED_PACKAGE_SPEC_LIST="$SPECIFIED_PACKAGE_SPEC_LIST $(inspect_package_spec "$PACKAGE" $SPECIFIED_TARGET)"
    done

    SPECIFIED_PACKAGE_SPEC_LIST=${SPECIFIED_PACKAGE_SPEC_LIST#' '}

    #echo "SPECIFIED_PACKAGE_SPEC_LIST=$SPECIFIED_PACKAGE_SPEC_LIST"

    #########################################################################################

    if [ "$LOG_LEVEL" = 0 ] ; then
        exec 1>/dev/null
        exec 2>&1
    else
        if [ -z "$LOG_LEVEL" ] ; then
            LOG_LEVEL=1
        fi
    fi

    #########################################################################################

    if [ -z "$PROFILE" ] ; then
        PROFILE=release
    fi

    #########################################################################################

    if [ -z "$ENABLE_STRIP" ] ; then
        case $PROFILE in
            debug)   ENABLE_STRIP=no  ;;
            release) ENABLE_STRIP=all ;;
        esac
    fi
}

# https://www.gnu.org/software/gettext/manual/html_node/config_002eguess.html
# https://git.savannah.gnu.org/cgit/config.git/tree/
  __update_config_sub_guess() {
    UPDATE_GNU_CONFIG_OLDCWD="$PWD"

    run cd "$SESSION_DIR"

    if [ -f config/config.sub ] && [ -f config/config.guess ] ; then
        CONFIG_FILE_DIR="$SESSION_DIR/config"
    else
        if [    -d config ] ; then
            rm -rf config
        fi

        if run git_checkout https://github.com/leleliu008/gnu-config --depth=1 -C config ; then
            CONFIG_FILE_DIR="$SESSION_DIR/config"
        elif run git clone --depth 1 https://git.savannah.gnu.org/git/config.git ; then
            CONFIG_FILE_DIR="$SESSION_DIR/config"
        else
            if  run curl -L -o _config.sub   "'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'" &&
                sh _config.sub x86_64-pc-linux &&
                run curl -L -o _config.guess "'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'" &&
                sh _config.guess > /dev/null ; then
                run chmod +x _config.guess
                run chmod +x _config.sub
                run mv _config.guess config.guess
                run mv _config.sub   config.sub
                CONFIG_FILE_DIR="$SESSION_DIR"
            elif run curl -L -o _config.sub   'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub' &&
                sh _config.sub x86_64-pc-linux &&
                run curl -L -o _config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess' &&
                sh _config.guess > /dev/null ; then
                run chmod +x _config.guess
                run chmod +x _config.sub
                run mv _config.guess config.guess
                run mv _config.sub   config.sub
                CONFIG_FILE_DIR="$SESSION_DIR"
            else
                CONFIG_FILE_DIR="$PPKG_CORE_DIR"
            fi
        fi
    fi

    run cd "$UPDATE_GNU_CONFIG_OLDCWD"

    find -type f -name config.sub   -exec cp -vf "$CONFIG_FILE_DIR/config.sub"   {} \;
    find -type f -name config.guess -exec cp -vf "$CONFIG_FILE_DIR/config.guess" {} \;
}

# should run in subshell
install_the_given_native_package() {
    [ -z "$1" ] && abort 1 "install_the_given_native_package <PACKAGE-NAME> , <PACKAGE-NAME> is unspecified."

    unset PACKAGE_SRC_URL
    unset PACKAGE_SRC_URI
    unset PACKAGE_SRC_SHA

    unset PACKAGE_DEP_PKG
    unset PACKAGE_DEP_AUX
    unset PACKAGE_DEP_RUN

    unset PACKAGE_DOPATCH
    unset PACKAGE_INSTALL
    unset PACKAGE_DOTWEAK

    if [ "$1" = 'perl-XML-Parser' ] ; then
        native_package_info_perl_XML_Parser
    else
        native_package_info_$1
    fi

    #########################################################################################

    for PACKAGE_DEPENDENCY in $PACKAGE_DEP_PKG
    do
        (install_the_given_native_package "$PACKAGE_DEPENDENCY")
    done

    #########################################################################################

    printf '\n%b\n' "${COLOR_PURPLE}=>> install native package : $1${COLOR_OFF}"

    if [ -f "$NATIVE_PACKAGE_INSTALLED_ROOT/$1/receipt.txt" ] ; then
        note "native package '$1' already has been installed, skipped."
        return 0
    fi

    #########################################################################################

    for UPPM_PACKAGE_NAME in $PACKAGE_DEP_AUX
    do
        run "$UPPM" install "$UPPM_PACKAGE_NAME" "$UPPM_INSTALL_ARGS"

        UPPM_PACKAGE_INSTALLED_DIR="$UPPM_HOME/installed/$UPPM_PACKAGE_NAME"

        if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/bin" ] ; then
            PATH="$UPPM_PACKAGE_INSTALLED_DIR/bin:$PATH"
        fi

        if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            PATH="$UPPM_PACKAGE_INSTALLED_DIR/sbin:$PATH"
        fi
    done

    #########################################################################################

    PACKAGE_INSTALL_UTS=
    PACKAGE_INSTALL_UTS="$(date +%s)"

    PACKAGE_INSTALL_SHA=
    PACKAGE_INSTALL_SHA="$(
{
    sha256sum <<EOF
$1:$PACKAGE_SRC_URL:$$:$PACKAGE_INSTALL_UTS
EOF
} | cut -d ' ' -f1)"

    #########################################################################################

    PACKAGE_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_INSTALL_SHA"

    PACKAGE_SRC_FILETYPE="$(filetype_from_url "$PACKAGE_SRC_URL")"
    PACKAGE_SRC_FILENAME="$PACKAGE_SRC_SHA$PACKAGE_SRC_FILETYPE"
    PACKAGE_SRC_FILEPATH="$PPKG_DOWNLOADS_DIR/$PACKAGE_SRC_FILENAME"

    PACKAGE_WORKING_DIR="$SESSION_DIR/native/$1"

    #########################################################################################

    # override the default search directory (usually /usr/lib/pkgconfig:/usr/share/pkgconfig)
    # because we only want to use our own
    export PKG_CONFIG_LIBDIR="$PACKAGE_WORKING_DIR/lib/pkgconfig"
    export PKG_CONFIG_PATH="$PACKAGE_WORKING_DIR/lib/pkgconfig:$PKG_CONFIG_PATH"
    export ACLOCAL_PATH="$PACKAGE_WORKING_DIR/share/aclocal"
    export CPPFLAGS="-I$PACKAGE_WORKING_DIR/include $CPPFLAGS"
    export LDFLAGS="-L$PACKAGE_WORKING_DIR/lib -Wl,-rpath,$PACKAGE_INSTALL_DIR/lib $LDFLAGS"

    for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
    do
        DEPENDENT_PACKAGE_INSTALLED_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME"

        if [ -d  "$DEPENDENT_PACKAGE_INSTALLED_DIR/include" ] ; then
            CPPFLAGS="-I$DEPENDENT_PACKAGE_INSTALLED_DIR/include $CPPFLAGS"
        fi

        if [ -d  "$DEPENDENT_PACKAGE_INSTALLED_DIR/lib" ] ; then
            LDFLAGS="-L$DEPENDENT_PACKAGE_INSTALLED_DIR/lib -Wl,-rpath,$DEPENDENT_PACKAGE_INSTALLED_DIR/lib $LDFLAGS"
        fi

        if [ -d  "$DEPENDENT_PACKAGE_INSTALLED_DIR/bin" ] ; then
            PATH="$DEPENDENT_PACKAGE_INSTALLED_DIR/bin:$PATH"
        fi

        if [ -d  "$DEPENDENT_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            PATH="$DEPENDENT_PACKAGE_INSTALLED_DIR/sbin:$PATH"
        fi

        if [ -d          "$DEPENDENT_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then
            ACLOCAL_PATH="$DEPENDENT_PACKAGE_INSTALLED_DIR/share/aclocal:$ACLOCAL_PATH"
        fi

        for d in lib share
        do
            DEPENDENT_PACKAGE_PKGCONF_DIR="$DEPENDENT_PACKAGE_INSTALLED_DIR/$d/pkgconfig"

            if [ -d "$DEPENDENT_PACKAGE_PKGCONF_DIR" ] ; then
                PKG_CONFIG_PATH="$DEPENDENT_PACKAGE_PKGCONF_DIR:$PKG_CONFIG_PATH"
                break
            fi
        done
    done

    #########################################################################################

    wfetch "$PACKAGE_SRC_URL" --uri="$PACKAGE_SRC_URI" --sha256="$PACKAGE_SRC_SHA" -o "$PACKAGE_SRC_FILEPATH"

    #########################################################################################

    run install -d "$PACKAGE_WORKING_DIR/src"
    run cd         "$PACKAGE_WORKING_DIR/src"

    #########################################################################################

    run bsdtar xf "$PACKAGE_SRC_FILEPATH" --strip-components=1 --no-same-owner

    #########################################################################################

    if [ -n  "$PACKAGE_DOPATCH" ] ; then
        eval "$PACKAGE_DOPATCH"
    fi

    #########################################################################################

    if [ -z "$PACKAGE_INSTALL" ] ; then
        abort 1 "PACKAGE_INSTALL variable is not set for native package '$1'"
    fi

    case "${PACKAGE_INSTALL%% *}" in
        configure)
            __update_config_sub_guess
            PACKAGE_INSTALL="run ./$PACKAGE_INSTALL --prefix=$PACKAGE_INSTALL_DIR && run gmake --jobs=$BUILD_NJOBS && run gmake install"
            ;;
        config)
            PACKAGE_INSTALL="run ./$PACKAGE_INSTALL --prefix=$PACKAGE_INSTALL_DIR && run gmake --jobs=$BUILD_NJOBS && run gmake install_sw"
            ;;
        perl)
            PACKAGE_INSTALL="run   $PACKAGE_INSTALL --prefix=$PACKAGE_INSTALL_DIR && run gmake --jobs=$BUILD_NJOBS && run gmake install && run install -d $PACKAGE_INSTALL_DIR"
            ;;
        cmake)
            PACKAGE_INSTALL="run $PACKAGE_INSTALL -DCMAKE_INSTALL_PREFIX=$PACKAGE_INSTALL_DIR -DENABLE_TESTING=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Release -G Ninja -S . -B build.d && run cmake --build build.d -- -j$BUILD_NJOBS && run cmake --install build.d"
            ;;
        gmake)
            PACKAGE_INSTALL="run $PACKAGE_INSTALL"
            ;;
    esac

    eval "$PACKAGE_INSTALL"

    #########################################################################################

    run cd "$PACKAGE_INSTALL_DIR"

    #########################################################################################

    if [ -n  "$PACKAGE_DOTWEAK" ] ; then
        eval "$PACKAGE_DOTWEAK"
    fi

    #########################################################################################

    run cd "$PACKAGE_INSTALL_DIR"

    #########################################################################################

    cat > buildon.yml <<EOF
os-arch: $NATIVE_PLATFORM_ARCH
os-kind: $NATIVE_PLATFORM_KIND
os-type: $NATIVE_PLATFORM_TYPE
os-libc: $NATIVE_PLATFORM_LIBC
os-code: $NATIVE_PLATFORM_CODE
os-name: $NATIVE_PLATFORM_NAME
os-vers: $NATIVE_PLATFORM_VERS
os-ncpu: $NATIVE_PLATFORM_NCPU
os-euid: $NATIVE_PLATFORM_EUID
os-egid: $NATIVE_PLATFORM_EGID
EOF

    #########################################################################################

    cat > toolchain.txt <<EOF
     CC='$CC'
    CXX='$CXX'
     AS='$AS'
     LD='$LD'
     AR='$AR'
 RANLIB='$RANLIB'
SYSROOT='$SYSROOT'
EOF

    #########################################################################################

    cat > receipt.txt <<EOF
PACKAGE_SRC_URL='$PACKAGE_SRC_URL'
PACKAGE_SRC_URI='$PACKAGE_SRC_URI'
PACKAGE_SRC_SHA='$PACKAGE_SRC_SHA'

PACKAGE_DEP_PKG='$PACKAGE_DEP_PKG'
PACKAGE_DEP_AUX='$PACKAGE_DEP_AUX'
PACKAGE_DEP_RUN='$PACKAGE_DEP_RUN'

PACKAGE_DOPATCH='$PACKAGE_DOPATCH'
PACKAGE_DOTWEAK='$PACKAGE_DOTWEAK'
PACKAGE_INSTALL='$PACKAGE_INSTALL'
PACKAGE_INSTALL_UTS='$PACKAGE_INSTALL_UTS'
EOF

    #########################################################################################

    run cd "$NATIVE_PACKAGE_INSTALLED_ROOT"
    run ln -s -f -T "$PACKAGE_INSTALL_SHA" "$1"
}

native_package_info_libz() {
    PACKAGE_SRC_URL='https://zlib.net/zlib-1.3.1.tar.gz'
    PACKAGE_SRC_SHA='9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23'
    PACKAGE_DEP_AUX='gsed cmake ninja'
    PACKAGE_DOPATCH='gsed -i "s|/share/pkgconfig|/lib/pkgconfig|" CMakeLists.txt'
    PACKAGE_INSTALL='cmake -DZLIB_BUILD_EXAMPLES=OFF -G Ninja'
}

native_package_info_libopenssl() {
    PACKAGE_SRC_URL='https://www.openssl.org/source/openssl-3.3.1.tar.gz'
    PACKAGE_SRC_SHA='777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DOPATCH='
    case $NATIVE_PLATFORM_ARCH in
        armv7l) gsed -i "s|armv7-a|armv7-a+fp|g" util/perl/OpenSSL/config.pm
    esac'
    PACKAGE_INSTALL='config no-tests no-ssl3 no-ssl3-method no-zlib --libdir=lib --openssldir=etc/ssl'
    # https://github.com/openssl/openssl/blob/master/INSTALL.md
}

native_package_info_libtool() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/libtool/libtool-2.4.7.tar.xz'
    PACKAGE_SRC_SHA='4f7f217f057ce655ff22559ad221a0fd8ef84ad1fc5fcb6990cecc333aa1635d'
    PACKAGE_INSTALL='configure --enable-ltdl-install'
    PACKAGE_DEP_AUX='gm4 gmake'
    PACKAGE_DOTWEAK='
run ln -s libtool    bin/glibtool
run ln -s libtoolize bin/glibtoolize
'
}

native_package_info_texinfo() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/texinfo/texinfo-7.2.tar.xz'
    PACKAGE_SRC_SHA='0329d7788fbef113fa82cb80889ca197a344ce0df7646fe000974c5d714363a6'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_DOPATCH='gsed -i "/libintl/d" tp/Texinfo/XS/parsetexi/api.c'
    PACKAGE_INSTALL='configure --with-included-regex --enable-threads=posix --disable-nls'
}

native_package_info_autoconf() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz'
    PACKAGE_SRC_SHA='431075ad0bf529ef13cb41e9042c542381103e80015686222b8a9d4abef42a1c'
    PACKAGE_DEP_AUX='perl gm4 gmake'
    PACKAGE_DEP_RUN='perl gm4'
    PACKAGE_INSTALL='configure'
}

native_package_info_automake() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/automake/automake-1.16.5.tar.xz'
    PACKAGE_SRC_SHA='f01d58cd6d9d77fbdca9eb4bbd5ead1988228fdb73d6f7a201f5f8d6b118b469'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_DEP_PKG='autoconf'
    PACKAGE_INSTALL='configure'
}

native_package_info_help2man() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/help2man/help2man-1.49.3.tar.xz'
    PACKAGE_SRC_SHA='4d7e4fdef2eca6afe07a2682151cea78781e0a4e8f9622142d9f70c083a2fd4f'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_INSTALL='configure'
    PACKAGE_DOTWEAK='gsed -i "1c #!$UPPM_HOME/installed/perl/bin/perl -w" bin/help2man'
}

native_package_info_libexpat() {
    PACKAGE_SRC_URL='https://github.com/libexpat/libexpat/releases/download/R_2_6_4/expat-2.6.4.tar.xz'
    PACKAGE_SRC_SHA='a695629dae047055b37d50a0ff4776d1d45d0a4c842cf4ccee158441f55ff7ee'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='configure --disable-dependency-tracking --enable-static --enable-shared --without-xmlwf --without-tests --without-examples --without-docbook'
}

native_package_info_intltool() {
    PACKAGE_SRC_URL='https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz'
    PACKAGE_SRC_URI='https://fossies.org/linux/privat/intltool-0.51.0.tar.gz'
    PACKAGE_SRC_SHA='67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_DEP_PKG='libexpat perl-XML-Parser'
    PACKAGE_INSTALL='configure'
}

native_package_info_perl_XML_Parser() {
    PACKAGE_SRC_URL='https://cpan.metacpan.org/authors/id/T/TO/TODDR/XML-Parser-2.47.tar.gz'
    PACKAGE_SRC_SHA='ad4aae643ec784f489b956abe952432871a622d4e2b5c619e8855accbfc4d1d8'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_DEP_PKG='libexpat'
    PACKAGE_DOPATCH='
run export EXPATLIBPATH="$NATIVE_PACKAGE_INSTALLED_ROOT/libexpat/lib"
run export EXPATINCPATH="$NATIVE_PACKAGE_INSTALLED_ROOT/libexpat/include"
run gsed -i "\"/check_lib/a not_execute,\"" Makefile.PL
'
    if [ "$NATIVE_PLATFORM_KIND" = darwin ] ; then
        PACKAGE_INSTALL='perl Makefile.PL'
    else
        PACKAGE_INSTALL='perl Makefile.PL LDDLFLAGS="\"-shared -L$NATIVE_PACKAGE_INSTALLED_ROOT/libexpat/lib -Wl,-rpath,$NATIVE_PACKAGE_INSTALLED_ROOT/libexpat/lib\""'
    fi
}

native_package_info_libiconv() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/libiconv/libiconv-1.18.tar.gz'
    PACKAGE_SRC_SHA='3b08f5f4f9b4eb82f151a7040bfd6fe6c6fb922efe4b1659c66ea933276965e8'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='configure --disable-dependency-tracking --enable-static --enable-shared --enable-extra-encodings'
}

native_package_info_libxml2() {
    PACKAGE_SRC_URL='https://download.gnome.org/sources/libxml2/2.13/libxml2-2.13.8.tar.xz'
    PACKAGE_SRC_SHA='277294cb33119ab71b2bc81f2f445e9bc9435b893ad15bb2cd2b0e859a0ee84a'
    PACKAGE_DEP_PKG='libz libiconv'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='configure --with-zlib --with-python --with-iconv="$NATIVE_PACKAGE_INSTALLED_ROOT/libiconv" --without-lzma --without-readline --without-coverage --without-debug --enable-ipv6 --enable-static --enable-shared LIBS=-liconv'
}

native_package_info_itstool() {
    PACKAGE_SRC_URL='https://github.com/itstool/itstool/archive/2.0.7.tar.gz'
    PACKAGE_SRC_SHA='fba78a37dc3535e4686c7f57407b97d03c676e3a57beac5fb2315162b0cc3176'
    PACKAGE_DEP_AUX='perl python3 gmake'
    PACKAGE_DEP_RUN='perl python3'
    PACKAGE_DEP_PKG='libxml2 autoconf automake'
    PACKAGE_INSTALL='configure'
    PACKAGE_DOPATCH='
    run autoreconf -ivf
    export PYTHON="$(command -v python3)"
    export PYTHONPATH="$NATIVE_PACKAGE_INSTALLED_ROOT/libxml2/lib/python3.11/site-packages"
    '
    PACKAGE_DOTWEAK='
run mv bin/itstool bin/itstool.py
cat > bin/itstool <<EOF
#!/bin/sh
export PYTHONPATH="$PYTHONPATH"
exec "$PYTHON" "$PACKAGE_INSTALL_DIR/bin/itstool.py" "\$@"
EOF
run chmod +x bin/itstool
    '
}

native_package_info_autoconf_archive() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/autoconf-archive/autoconf-archive-2024.10.16.tar.xz'
    PACKAGE_SRC_SHA='7bcd5d001916f3a50ed7436f4f700e3d2b1bade3ed803219c592d62502a57363'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='configure'
}

native_package_info_netsurf_buildsystem() {
    PACKAGE_SRC_URL='https://download.netsurf-browser.org/libs/releases/buildsystem-1.10.tar.gz'
    PACKAGE_SRC_SHA='3d3e39d569e44677c4b179129bde614c65798e2b3e6253160239d1fd6eae4d79'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='gmake install "PREFIX=$PACKAGE_INSTALL_DIR"'
}

# }}}
##############################################################################
# {{{ __install_the_given_package

__install_the_given_package_onexit() {
    is_package_installed "$PACKAGE_SPEC" || {
        if [ -n "$PACKAGE_WORKING_DIR" ] && [ -d "$PACKAGE_WORKING_DIR" ] ; then
            abort 1 "package installation failure: $PACKAGE_SPEC, if you want to figure out what had happeded, please change to the working directory: $PACKAGE_WORKING_DIR"
        else
            abort 1 "package installation failure: $PACKAGE_SPEC\n"
        fi
    }
}

# Note: this function must run in a subshell
__install_the_given_package() {
    printf '%b\n' "${COLOR_PURPLE}>>> Installation ${COLOR_OFF}${COLOR_GREEN}${1}${COLOR_OFF}${COLOR_PURPLE} start${COLOR_OFF}"

    trap  __install_the_given_package_onexit EXIT

    #########################################################################################

    STATIC_LIBRARY_SUFFIX='.a'

    if [ "$TARGET_PLATFORM_NAME" = macos ] ; then
        unset REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE
        SHARED_LIBRARY_SUFFIX='.dylib'
    else
        SHARED_LIBRARY_SUFFIX='.so'
    fi

    #########################################################################################

    if [ "$NATIVE_PLATFORM_KIND" = linux ] ; then
        NATIVE_PLATFORM_SPEC="$NATIVE_PLATFORM_TYPE-$NATIVE_PLATFORM_LIBC-$NATIVE_PLATFORM_ARCH"
    else
        NATIVE_PLATFORM_SPEC="$NATIVE_PLATFORM_TYPE-$NATIVE_PLATFORM_VERS-$NATIVE_PLATFORM_ARCH"
    fi

    if [ "$TARGET_PLATFORM_SPEC" = "$NATIVE_PLATFORM_SPEC" ] ; then
        CROSS_COMPILING=0
    else
        CROSS_COMPILING=1
    fi

    #########################################################################################

    cat <<EOF
      TIMESTAMP_UNIX = $TIMESTAMP_UNIX

NATIVE_PLATFORM_KIND = $NATIVE_PLATFORM_KIND
NATIVE_PLATFORM_TYPE = $NATIVE_PLATFORM_TYPE
NATIVE_PLATFORM_CODE = $NATIVE_PLATFORM_CODE
NATIVE_PLATFORM_NAME = $NATIVE_PLATFORM_NAME
NATIVE_PLATFORM_VERS = $NATIVE_PLATFORM_VERS
NATIVE_PLATFORM_ARCH = $NATIVE_PLATFORM_ARCH
NATIVE_PLATFORM_NCPU = $NATIVE_PLATFORM_NCPU
NATIVE_PLATFORM_LIBC = $NATIVE_PLATFORM_LIBC
NATIVE_PLATFORM_EUID = $NATIVE_PLATFORM_EUID
NATIVE_PLATFORM_EGID = $NATIVE_PLATFORM_EGID

TARGET_PLATFORM_NAME = $TARGET_PLATFORM_NAME
TARGET_PLATFORM_VERS = $TARGET_PLATFORM_VERS
TARGET_PLATFORM_ARCH = $TARGET_PLATFORM_ARCH

PPKG_ARG0            = $PPKG_ARG0
PPKG_ARG1            = $PPKG_ARG1
PPKG_ARGV            = $PPKG_ARGV
PPKG_PATH            = $PPKG_PATH
PPKG_HOME            = $PPKG_HOME
PPKG_VERSION         = $PPKG_VERSION
PPKG_URL_TRANSFORM   = $PPKG_URL_TRANSFORM

     CROSS_COMPILING = $CROSS_COMPILING

           LOG_LEVEL = $LOG_LEVEL
             PROFILE = $PROFILE

       ENABLE_CCACHE = $ENABLE_CCACHE
REQUEST_TO_KEEP_SESSION_DIR = $REQUEST_TO_KEEP_SESSION_DIR
REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON = $REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON
REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE = $REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE
EOF

    #########################################################################################

    PACKAGE_FORMULA_FILEPATH="$SESSION_DIR/$PACKAGE_NAME.yml"

    step "load formula"

    if [ "$DUMP_FORMULA" = 1 ] ; then
        if command -v bat > /dev/null ; then
            bat --language=yaml --paging=never "$PACKAGE_FORMULA_FILEPATH"
        else
            cat "$PACKAGE_FORMULA_FILEPATH"
        fi
    fi

    __load_formula_of_the_given_package "$PACKAGE_NAME" "$PACKAGE_FORMULA_FILEPATH"

    #########################################################################################

    unset PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE
    unset PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE

    [ "$PACKAGE_PKGTYPE" = exe ] && {
        unset PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE
        unset PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE

        case $PACKAGE_LINKAGE in
            '')
                PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=1
                PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=1
                ;;
            static)
                PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=1
                PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=0
                ;;
            static/pie)
                PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=1
                PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=0
                ;;
            shared)
                PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=0
                PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=1
                ;;
            shared/most)
                PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=0
                PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=0
                ;;
            *)  abort 1 "unsupported linkage: $PACKAGE_LINKAGE"
        esac

        if [ "$REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
            if [ "$PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=1
            else
                if [ "$PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                    note "You are requesting to create fully statically linked executables, but package '$PACKAGE_NAME' is supposed to create dynamically linked executables, so we will downgrade to create mostly statically linked executables."
                    export PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=1
                else
                    note "You are requesting to create fully statically linked executables, but package '$PACKAGE_NAME' is supposed to create dynamically linked executables."
                fi
            fi
        else
            if [ "$PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                export PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=1
            fi
        fi
    }

    #########################################################################################

    if [ "$PACKAGE_SUPPORT_BUILD_IN_PARALLEL" = 1 ] ; then
        if [ -z "$BUILD_NJOBS" ] ; then
            BUILD_NJOBS="$NATIVE_PLATFORM_NCPU"
        fi
    else
        BUILD_NJOBS=1
    fi

    #########################################################################################

    if [ "$PACKAGE_LTOABLE" != 1 ] ; then
        ENABLE_LTO=0
    fi

    #########################################################################################

    PACKAGE_INSTALL_UTS=
    PACKAGE_INSTALL_UTS="$(date +%s)"

    PACKAGE_INSTALL_SHA=
    PACKAGE_INSTALL_SHA="$(
{
    sha256sum <<EOF
$PACKAGE_NAME:$$:$PACKAGE_INSTALL_UTS
EOF
} | cut -d ' ' -f1)"

    #########################################################################################

    PACKAGE_UUID="$TARGET_PLATFORM_SPEC/$PACKAGE_INSTALL_SHA"

    #########################################################################################

    PACKAGE_WORKING_DIR="$SESSION_DIR/$PACKAGE_SPEC"
    PACKAGE_BCACHED_DIR="$PACKAGE_WORKING_DIR/src/_"
    PACKAGE_BSCRIPT_DIR="$PACKAGE_WORKING_DIR/src/$PACKAGE_BSCRIPT"
    PACKAGE_BSCRIPT_DIR="${PACKAGE_BSCRIPT_DIR%/}"
    PACKAGE_INSTALL_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_UUID"

    #########################################################################################

    step "calculate working/install directory"

    cat <<EOF
PACKAGE_WORKING_DIR = $PACKAGE_WORKING_DIR
PACKAGE_BSCRIPT_DIR = $PACKAGE_BSCRIPT_DIR
PACKAGE_BCACHED_DIR = $PACKAGE_BCACHED_DIR
PACKAGE_INSTALL_DIR = $PACKAGE_INSTALL_DIR
EOF

    #########################################################################################

    step "create the working directory and change to it"

    run install -d "$PACKAGE_WORKING_DIR"
    run         cd "$PACKAGE_WORKING_DIR"

    run install -d src/_ fix res bin lib include map

    #########################################################################################

    PACKAGE_INSTALLING_SRC_DIR="$PACKAGE_WORKING_DIR/src"
    PACKAGE_INSTALLING_FIX_DIR="$PACKAGE_WORKING_DIR/fix"
    PACKAGE_INSTALLING_RES_DIR="$PACKAGE_WORKING_DIR/res"
    PACKAGE_INSTALLING_BIN_DIR="$PACKAGE_WORKING_DIR/bin"
    PACKAGE_INSTALLING_LIB_DIR="$PACKAGE_WORKING_DIR/lib"
    PACKAGE_INSTALLING_INC_DIR="$PACKAGE_WORKING_DIR/include"

    #########################################################################################

    unset RECURSIVE_DEPENDENT_PACKAGE_NAMES

    [ -n "$PACKAGE_DEP_PKG" ] && {
        step "calculate dependency list of $1"

        unset STACK

        for item in $PACKAGE_DEP_PKG
        do
            if [ -z "$item" ] ; then
                STACK="$item"
            else
                STACK="$STACK;$item"
            fi
        done

        while [ -n "$STACK" ]
        do
            case $STACK in
                *\;*) TOPE="${STACK##*;}" ; STACK="${STACK%;*}" ;;
                *)    TOPE="${STACK}"     ; STACK=
            esac

            RECURSIVE_DEPENDENT_PACKAGE_NAMES2="$TOPE"

            for item in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
            do
                if [ "$item" != "$TOPE" ] ; then
                    RECURSIVE_DEPENDENT_PACKAGE_NAMES2="$RECURSIVE_DEPENDENT_PACKAGE_NAMES2 $item"
                fi
            done

            RECURSIVE_DEPENDENT_PACKAGE_NAMES="$RECURSIVE_DEPENDENT_PACKAGE_NAMES2"

            unset TOPE_UPPERCASE_UNDERSCORE
            TOPE_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$TOPE" | tr '@+-.' '_' | tr a-z A-Z)

            for item in $(eval echo \$PACKAGE_DEP_PKG_"${TOPE_UPPERCASE_UNDERSCORE}")
            do
                if [ -z "$item" ] ; then
                    STACK="$item"
                else
                    STACK="$STACK;$item"
                fi
            done
        done

        printf '%s\n' "$RECURSIVE_DEPENDENT_PACKAGE_NAMES"
    }

    #########################################################################################

    # https://www.gnu.org/software/automake/manual/html_node/Macro-Search-Path.html
    export ACLOCAL_PATH="$PPKG_CORE_DIR/share/aclocal"

    # https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
    export XDG_DATA_DIRS="$PPKG_CORE_DIR/share/mime"

    export PKG_CONFIG_PATH="$PPKG_CORE_DIR/lib/pkgconfig"

    # override the default search directory (usually /usr/lib/pkgconfig:/usr/share/pkgconfig)
    export PKG_CONFIG_LIBDIR="$PPKG_CORE_DIR/lib/pkgconfig"

    if [ "$DEBUG_PKG_CONFIG" = 1 ] ; then
        export PKG_CONFIG_DEBUG_SPEW='set'
    fi

    #########################################################################################

    [ -n "$PACKAGE_DEP_PKG" ] && {
        if [ "$CROSS_COMPILING" = 1 ] ; then
            ROOTDIR="$NATIVE_PACKAGE_INSTALLED_ROOT"
        else
            ROOTDIR="$PPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC"
        fi

        for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
        do
            DEPENDENT_PACKAGE_INSTALL_DIR="$ROOTDIR/$DEPENDENT_PACKAGE_NAME"

            for d in bin sbin
            do
                BINDIR="$DEPENDENT_PACKAGE_INSTALL_DIR/$d"

                if [ -d  "$BINDIR" ] ; then
                    PATH="$BINDIR:$PATH"
                fi
            done

            if [ "$DEPENDENT_PACKAGE_NAME" = docbook ] ; then
                # http://xmlsoft.org/xslt/xsltproc.html
                export XML_CATALOG_FILES="$DEPENDENT_PACKAGE_INSTALL_DIR/catalog.xml"
                printf '%s\n' "XML_CATALOG_FILES=$XML_CATALOG_FILES"
            fi
        done
    }

    #########################################################################################

    [ -n "$PACKAGE_DEP_PKG" ] && {
        step "generate  dependency tree of $1"

        unset DOT_CONTENT
        unset D2__CONTENT

        STACK="$PACKAGE_NAME"

        while [ -n "$STACK" ]
        do
            case $STACK in
                *\;*) TOPE="${STACK##*;}" ; STACK="${STACK%;*}" ;;
                *)    TOPE="${STACK}"     ; STACK=
            esac

            unset TOPE_UPPERCASE_UNDERSCORE
            TOPE_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$TOPE" | tr '@+-.' '_' | tr a-z A-Z)

            TOPE_DEP_PKG="$(eval echo \$PACKAGE_DEP_PKG_"${TOPE_UPPERCASE_UNDERSCORE}")"

            [ -z "$TOPE_DEP_PKG" ] && continue

            DOUBLE_QUOTE_LIST=

            for item in $TOPE_DEP_PKG
            do
                if [ "$item" = "$TOPE" ] ; then
                    abort 1 "package '$TOPE' depends itself."
                fi

                D2__CONTENT="$D2__CONTENT
$TOPE -> $item"

                DOUBLE_QUOTE_LIST="$DOUBLE_QUOTE_LIST \"$item\""

                if [ -z "$STACK" ] ; then
                    STACK="$item"
                else
                    STACK="$STACK;$item"
                fi
            done

            DOT_CONTENT="$DOT_CONTENT
\"$TOPE\" -> {$DOUBLE_QUOTE_LIST }"
        done

        DOT_CONTENT="digraph G {
$DOT_CONTENT
}"

        ##################################################

        PACKAGE_DEPENDENCY_GRAPH_FILEPATH_D2_="$PACKAGE_WORKING_DIR/dependencies.d2"
        PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT="$PACKAGE_WORKING_DIR/dependencies.dot"
        PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX="$PACKAGE_WORKING_DIR/dependencies.box"

        ##################################################

        printf '%s\n' "$D2__CONTENT" > "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_D2_"
        printf '%s\n' "$DOT_CONTENT" > "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT"

        ##################################################

        # https://github.com/ggerganov/dot-to-ascii
        curl \
            -o "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX" \
            -s \
            -G \
            --data-urlencode "boxart=1" \
            --data-urlencode "src=$DOT_CONTENT" \
            "https://dot-to-ascii.ggerganov.com/dot-to-ascii.php" || true

        ##################################################

        DOT="$(command -v dot || command -v dot_static || true)"

        if [ -n "$DOT" ] ; then
            run "$DOT" -Tsvg -o "$PACKAGE_WORKING_DIR/dependencies.svg" "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT" || true
        else
            D2="$(command -v d2 || true)"

            if [ -n "$D2" ] ; then
                run "$D2" "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_D2_" "$PACKAGE_WORKING_DIR/dependencies.svg"
            fi
        fi

        ##################################################

        if [ -f "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX" ] ; then
            cat "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX"
        else
            cat "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT"
        fi
    }

    #########################################################################################

    if [ "$PACKAGE_USE_BSYSTEM_GMAKE" = 1 ] && [ "$EXPORT_COMPILE_COMMANDS_JSON" = 1 ] && [ "$BEAR_ENABLED" = 1 ] ; then
        PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP bear"
    fi

    if [ "$CCACHE_ENABLED" = 1 ] ; then
        PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP ccache"
    fi

    #########################################################################################

    unset PACKAGE_DEP_AUX_LIBZ
    unset PACKAGE_DEP_AUX_LIBOPENSSL

    # these native packages would be built from source locally due to they are not relocatable or libraries
    unset PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY

    #########################################################################################

    step "install needed packages via uppm"

    run "$UPPM" about
    run "$UPPM" update

    if [ -n "$SYSPM" ] ; then
        run "$UPPM" install $PACKAGE_DEP_UPP pkg-config patchelf tree

        if [ "$NATIVE_PLATFORM_KIND" = openbsd ] ; then
            for item in $PACKAGE_DEP_UPP
            do
                case $item in
                    golang)
                        GOLANG_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/golang"

                        [ -f "$GOLANG_INSTALL_DIR/ok.txt" ] || {
                            step "install golang"

                            SHA256='c51dc5d67cbf214d72555bcffedf9b509b599287d4567a85972782207310134b'
                            OUTPUT="$PPKG_DOWNLOADS_DIR/$SHA256.tgz"
                            wfetch 'https://go.dev/dl/go1.24.5.openbsd-amd64.tar.gz' --sha256="$SHA256" -o "$OUTPUT"

                            run install -d "$GOLANG_INSTALL_DIR"
                            run bsdtar xf "$OUTPUT" -C "$GOLANG_INSTALL_DIR" --strip-components=1
                            run touch "$GOLANG_INSTALL_DIR/ok.txt"
                        }

                        export PATH="$GOLANG_INSTALL_DIR/bin:$PATH"

                        break
                esac
            done
        fi
    else
        PACKAGE_DEP_AUX="$PACKAGE_DEP_UPP"
        PACKAGE_DEP_UPP=

        for UPPM_PACKAGE_NAME in $PACKAGE_DEP_AUX
        do
            case $UPPM_PACKAGE_NAME in
                libz)
                    PACKAGE_DEP_AUX_LIBZ=1
                    PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY libz"
                    ;;
                libopenssl)
                    PACKAGE_DEP_AUX_LIBOPENSSL=1
                    PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY libopenssl"
                    ;;
                automake)
                    PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY autoconf automake"
                    PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl gmake gm4"
                    ;;
                autoconf|libtool|texinfo|help2man|intltool)
                    PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY $UPPM_PACKAGE_NAME"
                    PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl gmake gm4"
                    ;;
                itstool)
                    PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY itstool"
                    PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl python3"
                    ;;
                cmake)
                    if [ "$NATIVE_PLATFORM_TYPE" = netbsd ] ; then
                        run $sudo pkgin -y update
                        run $sudo pkgin -y install cmake
                    else
                    PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP $UPPM_PACKAGE_NAME"
                    fi
                    ;;
                autoconf-archive)
                    PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY autoconf_archive"
                    ;;
                netsurf_buildsystem)
                    PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY $UPPM_PACKAGE_NAME"
                    ;;
                *)  PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP $UPPM_PACKAGE_NAME"
            esac
        done

        ####################################################################

        unset UPPM_INSTALL_ARGS

        if [ "$DUMP_UPPM" = 1 ] ; then
            UPPM_INSTALL_ARGS=-v
        fi

        ####################################################################

        for UPPM_PACKAGE_NAME in $PACKAGE_DEP_UPP pkg-config patchelf tree
        do
            run "$UPPM" install "$UPPM_PACKAGE_NAME" $UPPM_INSTALL_ARGS

            UPPM_PACKAGE_INSTALLED_DIR="$UPPM_HOME/installed/$UPPM_PACKAGE_NAME"

            if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/bin" ] ; then
                PATH="$UPPM_PACKAGE_INSTALLED_DIR/bin:$PATH"
            fi

            if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/sbin" ] ; then
                PATH="$UPPM_PACKAGE_INSTALLED_DIR/sbin:$PATH"
            fi

            if [ -d          "$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then
                ACLOCAL_PATH="$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal:$ACLOCAL_PATH"
            fi

            for d in lib share
            do
                UPPM_PACKAGE_PKGCONF_DIR="$UPPM_PACKAGE_INSTALLED_DIR/$d/pkgconfig"

                if [ -d "$UPPM_PACKAGE_PKGCONF_DIR" ] ; then
                    PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$UPPM_PACKAGE_PKGCONF_DIR"
                    break
                fi
            done

            case $UPPM_PACKAGE_NAME in
                swig)
                    # https://www.swig.org/Doc4.0/Library.html
                    X="$(ls $UPPM_PACKAGE_INSTALLED_DIR/share/swig/*/swig.swg)"
                    export SWIG_LIB="${X%/*}"
                    ;;
                file)
                    export MAGIC="$UPPM_PACKAGE_INSTALLED_DIR/share/misc/magic.mgc"
                    ;;
                docbook-xsl)
                    # http://xmlsoft.org/xslt/xsltproc.html
                    export XML_CATALOG_FILES="$UPPM_PACKAGE_INSTALLED_DIR/catalog.xml"
                    printf '%s\n' "XML_CATALOG_FILES=$XML_CATALOG_FILES"
            esac
        done
    fi

    #########################################################################################

    for NATIVE_PACKAGE_NAME in $PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY
    do
        (install_the_given_native_package "$NATIVE_PACKAGE_NAME")

        NATIVE_PACKAGE_INSTALLED_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$NATIVE_PACKAGE_NAME"

        if [ -d  "$NATIVE_PACKAGE_INSTALLED_DIR/include" ] ; then
            CPPFLAGS_FOR_BUILD="$CPPFLAGS_FOR_BUILD -I$NATIVE_PACKAGE_INSTALLED_DIR/include"
        fi

        if [ -d  "$NATIVE_PACKAGE_INSTALLED_DIR/lib" ] ; then
            LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -L$NATIVE_PACKAGE_INSTALLED_DIR/lib -Wl,-rpath,$NATIVE_PACKAGE_INSTALLED_DIR/lib"
        fi

        if [ -d  "$NATIVE_PACKAGE_INSTALLED_DIR/bin" ] ; then
            PATH="$NATIVE_PACKAGE_INSTALLED_DIR/bin:$PATH"
        fi

        if [ -d  "$NATIVE_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            PATH="$NATIVE_PACKAGE_INSTALLED_DIR/sbin:$PATH"
        fi

        if [ -d          "$NATIVE_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then
            ACLOCAL_PATH="$NATIVE_PACKAGE_INSTALLED_DIR/share/aclocal:$ACLOCAL_PATH"
        fi

        for d in lib share
        do
            NATIVE_PACKAGE_PKGCONF_DIR="$NATIVE_PACKAGE_INSTALLED_DIR/$d/pkgconfig"

            if [ -d "$NATIVE_PACKAGE_PKGCONF_DIR" ] ; then
                PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$NATIVE_PACKAGE_PKGCONF_DIR"
                break
            fi
        done
    done

    #########################################################################################

    [ -n "$PACKAGE_DEP_PYM" ] && {
        step "install needed python packages via pip"

        PYTHON3="$(command -v python3 || command -v python3.13 || command -v python3.12 || command -v python3.11 || command -v python3.10)" || abort 1 "command not found: python3"

        if [ -n "$SYSPM" ] ; then
            wfetch 'https://bootstrap.pypa.io/pip/pip.pyz'
            run "$PYTHON3" --version
            run "$PYTHON3" pip.pyz install --user --upgrade --break-system-packages "$PACKAGE_DEP_PYM"
        else
            run "$PYTHON3" --version
            run "$PYTHON3" -m pip install --upgrade pip
            run "$PYTHON3" -m pip install --upgrade "$PACKAGE_DEP_PYM"
        fi
    }

    #########################################################################################

    [ -n "$PACKAGE_DEP_PLM" ] && {
        step "install needed perl modules via cpan"

        unset PACKAGE_DEP_PLM_T1
        unset PACKAGE_DEP_PLM_T2

        for item in $PACKAGE_DEP_PLM
        do
            if [ "$item" = 'XML::Parser' ] ; then
                PACKAGE_DEP_PLM_T1='XML::Parser'
            else
                PACKAGE_DEP_PLM_T2="$PACKAGE_DEP_PLM_T2 $item"
            fi
        done

        if [ -n "$PACKAGE_DEP_PLM_T1" ] ; then
            (install_the_given_native_package perl_XML_Parser)
        fi

        if [ -n "$PACKAGE_DEP_PLM_T2" ] ; then
            PACKAGE_DEP_PLM_T2="${PACKAGE_DEP_PLM_T2# }"
        fi

        if [ -n "$PACKAGE_DEP_PLM_T2" ] ; then
            # Would you like to configure as much as possible automatically? [yes]
            # https://perldoc.perl.org/cpan#PERL_MM_USE_DEFAULT
            export PERL_MM_USE_DEFAULT=1
            run cpan "$PACKAGE_DEP_PLM_T2"
        fi

        if [ -d "$HOME/perl5/bin" ] ; then
            # cpan install to default local location
            bppend_to_PATH "$HOME/perl5/bin"
        fi
    }

    #########################################################################################

    [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && {
        if command -v cargo > /dev/null && command -v rustc > /dev/null ; then
            :
        else
            if [ "$GITHUB_ACTIONS" = true ] && [ "$CROSS_COMPILING" != 1 ] && [ "$NATIVE_PLATFORM_CODE" = alpine ] && [ -f /sbin/apk ] && [ -x /sbin/apk ] ; then
                run $sudo /sbin/apk update
                run $sudo /sbin/apk add rust cargo
            elif [ "$NATIVE_PLATFORM_KIND" = openbsd ] ; then
                # https://github.com/rust-lang/rustup/issues/2377
                # https://github.com/rust-lang/rustup/issues/2168
                run $sudo pkg_add rust
            else
                # https://www.rust-lang.org/tools/install
                note "${COLOR_GREEN}cargo rustc${COLOR_OFF} ${COLOR_YELLOW}commands are required, but it was not found, let's install it.${COLOR_OFF}"

                wfetch 'https://sh.rustup.rs' -o rustup-init.sh

                run bash rustup-init.sh -y && {
                    export CARGO_HOME="$HOME/.cargo"
                    export PATH="$CARGO_HOME/bin:$PATH"
                }
            fi
        fi
    }

    #########################################################################################

    step "locate needed tools"

    unset AUTORECONF
    unset AUTOCONF
    unset AUTOMAKE
    unset ACLOCAL
    unset PERL
    unset M4

    unset MESON
    unset CMAKE
    unset XMAKE
    unset GMAKE
    unset NINJA

    unset BEAR
    unset CCACHE
    unset PKG_CONFIG

    if [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] || [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] ; then
        AUTORECONF=$(command -v autoreconf) || abort 1 "command not found: autoreconf"
        AUTOCONF=$(command -v autoconf)     || abort 1 "command not found: autoconf"
        AUTOMAKE=$(command -v automake)     || abort 1 "command not found: automake"
        ACLOCAL=$(command -v aclocal)       || abort 1 "command not found: aclocal"
        PERL=$(command -v perl)             || abort 1 "command not found: perl"
        M4=$(command -v m4)                 || abort 1 "command not found: m4"

        run "$AUTORECONF" --version
        printf '\n'
        run "$AUTOCONF"   --version
        printf '\n'
        run "$AUTOMAKE"   --version
        printf '\n'
        run "$ACLOCAL"    --version
        printf '\n'
        run "$PERL"       --version
        printf '\n'
        run "$M4"         --version
        printf '\n'
    fi

    [ "$PACKAGE_USE_BSYSTEM_MESON" = 1 ] && {
        MESON=$(command -v meson) || abort 1 "command not found: meson"
        run "$MESON"      --version
        printf '\n'
    }

    [ "$PACKAGE_USE_BSYSTEM_CMAKE" = 1 ] && {
        CMAKE=$(command -v cmake) || abort 1 "command not found: cmake"
        run "$CMAKE"      --version
        printf '\n'
    }

    [ "$PACKAGE_USE_BSYSTEM_XMAKE" = 1 ] && {
        XMAKE=$(command -v xmake) || abort 1 "command not found: xmake"

        # error: Running xmake as root is extremely dangerous and no longer supported.
        # As xmake does not drop privileges on installation you would be giving all
        # build scripts full access to your system.
        # Or you can add `--root` option or XMAKE_ROOT=y to allow run as root temporarily.
        export XMAKE_ROOT=y

        run "$XMAKE"      --version
        printf '\n'
    }

    [ "$PACKAGE_USE_BSYSTEM_GMAKE" = 1 ] && {
        GMAKE=$(command -v gmake || command -v make) || abort 1 "command not found: gmake and make"
        run "$GMAKE"      --version
        printf '\n'
    }

    [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] && {
        NINJA=$(command -v ninja) || abort 1 "command not found: ninja"
        run "$NINJA"      --version
        printf '\n'
    }

    [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && {
        CARGO=$(command -v cargo)   || abort 1 "command not found: cargo"
        run "$CARGO"      --version
        printf '\n'

        RUSTC=$(command -v rustc) || abort 1 "command not found: rustc"
        run "$RUSTC"     --version
        printf '\n'
    }

    [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] && {
        GO=$(command -v go) || abort 1 "command not found: go"
        run "$GO"      version
        printf '\n'
    }

    [ "$CCACHE_ENABLED" = 1 ] && {
        CCACHE=$(command -v ccache) || abort 1 "command not found: ccache"
        run "$CCACHE"    --version
        printf '\n'
    }

    PKG_CONFIG=$(command -v pkg-config || command -v pkgconf) || abort 1 "command not found: pkg-config"

    run "$PKG_CONFIG"    --version
    printf '\n'

    unset  M4
    export M4="$(command -v m4 || true)"

    #########################################################################################

    step "dofetch"

    if [ -n "$PACKAGE_DOFETCH" ] ; then
        eval "
dofetch() {
$PACKAGE_DOFETCH
}"
        dofetch
    else
        case $PACKAGE_SRC_URL in
            '')
                if [ -n "$PACKAGE_GIT_URL" ] ; then
                    unset GIT_FETCH_URL

                    if [ -z "$PPKG_URL_TRANSFORM" ] ; then
                        GIT_FETCH_URL="$PACKAGE_GIT_URL"
                    else
                        GIT_FETCH_URL="$("$PPKG_URL_TRANSFORM" "$PACKAGE_GIT_URL")" || return 1
                    fi

                    if [ -z "$PACKAGE_GIT_SHA" ] ; then
                        if [ -z "$PACKAGE_GIT_REF" ] ; then
                            GIT_BRANCH_NAME=master
                            GIT_REF_SPEC="+HEAD:refs/remotes/origin/master"
                        else
                            GIT_BRANCH_NAME="$(basename "$PACKAGE_GIT_REF")"
                            GIT_REF_SPEC="+$PACKAGE_GIT_REF:refs/remotes/origin/$GIT_BRANCH_NAME"
                        fi
                    else
                        GIT_BRANCH_NAME=master
                        GIT_REF_SPEC="+$PACKAGE_GIT_SHA:refs/remotes/origin/master"
                    fi

                    if [ -z "$PACKAGE_GIT_NTH" ] ; then
                        PACKAGE_GIT_NTH=1
                    fi

                    if [ "$PACKAGE_GIT_NTH" -eq 0 ] ; then
                        if [ -f "$PACKAGE_SRC_FILEPATH/.git/shallow" ] ; then
                            GIT_FETCH_EXTRA_OPTIONS='--unshallow'
                        else
                            GIT_FETCH_EXTRA_OPTIONS=
                        fi
                    else
                        GIT_FETCH_EXTRA_OPTIONS="--depth=$PACKAGE_GIT_NTH"
                    fi

                    run cd "$PACKAGE_INSTALLING_SRC_DIR"

                    run git -c init.defaultBranch=master init
                    run git remote add origin "$GIT_FETCH_URL"
                    run git -c protocol.version=2 fetch --progress $GIT_FETCH_EXTRA_OPTIONS origin "$GIT_REF_SPEC"
                    run git checkout --progress --force -B "$GIT_BRANCH_NAME" "refs/remotes/origin/$GIT_BRANCH_NAME"

                    git_submodule_update_recursive
                fi
                ;;
            dir://*)
                note "$PACKAGE_SRC_URL is local path, no need to fetch."
                ;;
            file://*)
                note "$PACKAGE_SRC_URL is local path, no need to fetch."
                ;;
            *)  wfetch "$PACKAGE_SRC_URL" --uri="$PACKAGE_SRC_URI" --sha256="$PACKAGE_SRC_SHA" -o "$PACKAGE_SRC_FILEPATH"
        esac

        if [ -n    "$PACKAGE_FIX_URL" ] ; then
            wfetch "$PACKAGE_FIX_URL" --uri="$PACKAGE_FIX_URI" --sha256="$PACKAGE_FIX_SHA" -o "$PACKAGE_FIX_FILEPATH"
        fi

        if [ -n    "$PACKAGE_RES_URL" ] ; then
            wfetch "$PACKAGE_RES_URL" --uri="$PACKAGE_RES_URI" --sha256="$PACKAGE_RES_SHA" -o "$PACKAGE_RES_FILEPATH"
        fi
    fi

    #########################################################################################

    step "unpack/copy resources to proper location"

    if [ -n "$PACKAGE_SRC_FILEPATH" ] ; then
        case $PACKAGE_SRC_FILETYPE in
            .dir)
                if [ -d "$PACKAGE_SRC_FILEPATH" ] ; then
                    if [ -d "$PACKAGE_SRC_FILEPATH/.git" ] && command -v git > /dev/null ; then
                        PACKAGE_GIT_SHA=$(git -C "$PACKAGE_SRC_FILEPATH" rev-parse HEAD || true)
                    fi
                    run cp -r "$PACKAGE_SRC_FILEPATH/." "$PACKAGE_INSTALLING_SRC_DIR"
                else
                    abort 1 "src-url point to dir '$PACKAGE_SRC_FILEPATH' does not exist."
                fi
                ;;
            .git)
                if [ -z "$PACKAGE_GIT_SHA" ] ; then
                    PACKAGE_GIT_SHA="$(git rev-parse HEAD)"
                fi
                ;;
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                run bsdtar xf "$PACKAGE_SRC_FILEPATH" -C "$PACKAGE_INSTALLING_SRC_DIR" --strip-components 1 --no-same-owner
                ;;
            *)  run cp "$PACKAGE_SRC_FILEPATH" "$PACKAGE_INSTALLING_SRC_DIR/"
        esac
    fi

    if [ -n "$PACKAGE_FIX_FILEPATH" ] ; then
        case $PACKAGE_FIX_FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                run bsdtar xf "$PACKAGE_FIX_FILEPATH" -C "$PACKAGE_INSTALLING_FIX_DIR" --strip-components 1 --no-same-owner
                ;;
            *)  run cp "$PACKAGE_FIX_FILEPATH" "$PACKAGE_INSTALLING_FIX_DIR/"
                printf '%s|%s\n' "$PACKAGE_FIX_FILENAME" "$PACKAGE_FIX_OPT" > "$PACKAGE_INSTALLING_FIX_DIR/index"
        esac
    fi

    if [ -n "$PACKAGE_RES_FILEPATH" ] ; then
        case $PACKAGE_RES_FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                run bsdtar xf "$PACKAGE_RES_FILEPATH" -C "$PACKAGE_INSTALLING_RES_DIR" --strip-components 1 --no-same-owner
                ;;
            *)  run cp "$PACKAGE_RES_FILEPATH" "$PACKAGE_INSTALLING_RES_DIR/"
        esac
    fi

    for LINE in $PACKAGE_PATCHES
    do
        SHA="$(printf '%s\n' "$LINE" | cut -d '|' -f1)"
        URL="$(printf '%s\n' "$LINE" | cut -d '|' -f2)"
        URI="$(printf '%s\n' "$LINE" | cut -d '|' -f3)"
        OPT="$(printf '%s\n' "$LINE" | cut -d '|' -f4)"

        FILETYPE="$(filetype_from_url "$URL")"
        FILENAME="$SHA$FILETYPE"
        FILEPATH="$PPKG_DOWNLOADS_DIR/$FILENAME"

        wfetch "$URL" --uri="$URI" --sha256="$SHA" -o "$FILEPATH"

        case $FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                run bsdtar xf "$FILEPATH" -C "$PACKAGE_INSTALLING_FIX_DIR" --strip-components 1 --no-same-owner
                ;;
            *)  run cp "$FILEPATH" "$PACKAGE_INSTALLING_FIX_DIR/"
                printf '%s|%s\n' "$FILENAME" "$OPT" >> "$PACKAGE_INSTALLING_FIX_DIR/index"
        esac
    done

    for LINE in $PACKAGE_RESLIST
    do
        SHA="$(printf '%s\n' "$LINE" | cut -d '|' -f1)"
        URL="$(printf '%s\n' "$LINE" | cut -d '|' -f2)"
        URI="$(printf '%s\n' "$LINE" | cut -d '|' -f3)"
        DIR="$(printf '%s\n' "$LINE" | cut -d '|' -f4)"
        LEV="$(printf '%s\n' "$LINE" | cut -d '|' -f5)"

        [ -z "$LEV" ] && LEV=1

        FILETYPE="$(filetype_from_url "$URL")"
        FILENAME="$SHA$FILETYPE"
        FILEPATH="$PPKG_DOWNLOADS_DIR/$FILENAME"

        wfetch "$URL" --uri="$URI" --sha256="$SHA" -o "$FILEPATH"

        if [ -z "$DIR" ] ; then
            DEST="$PACKAGE_INSTALLING_RES_DIR"
        else
            DEST="$PACKAGE_INSTALLING_RES_DIR/$DIR"
            run install -d "$DEST"
        fi

        case $FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                run bsdtar xf "$FILEPATH" -C "$DEST" --strip-components "$LEV" --no-same-owner
                ;;
            *)  run cp "$FILEPATH" "$DEST/"
        esac
    done

    #########################################################################################

    if [ -n "$PACKAGE_DEP_RES" ] && [ "$TARGET_PLATFORM_NAME" = linux ] && [ "$TARGET_PLATFORM_VERS" = musl ] ; then
        for item in $PACKAGE_DEP_RES
        do
            case $item in
                sys/queue.h)
                    run cd "$PACKAGE_WORKING_DIR"
                    run install -d include/sys/
                    wfetch https://raw.githubusercontent.com/leleliu008/sys-queue.h/v1/sys-queue.h -o include/sys/queue.h --no-buffer
            esac
        done
    fi

    #########################################################################################

    if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
        step "tree files of the installing top directory"
        run tree --dirsfirst -L 2 "$PACKAGE_WORKING_DIR"

        step "list files of the installing src directory"
        run ls -l "$PACKAGE_INSTALLING_SRC_DIR"

        if [ -n "$PACKAGE_BSCRIPT" ] ; then
            step "list files of the installing build script directory"
            run ls -l "$PACKAGE_BSCRIPT_DIR"
        fi
    fi

    #########################################################################################

    if [ -n "$PACKAGE_DO12345" ] ; then
        step "build for native"

        NATIVE_BUILD_NEEDED=1

        NATIVE_INSTALLED_VERSION_TXT_FILEPATH="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_NAME/version.txt"

        [ -f "$NATIVE_INSTALLED_VERSION_TXT_FILEPATH" ] && {
            if [ "$(cat "$NATIVE_INSTALLED_VERSION_TXT_FILEPATH")" = "$PACKAGE_VERSION" ] ; then
                NATIVE_BUILD_NEEDED=0
                note "build for native already have been done, skipped."
            else
                note "build for native already have been done, but not the same version, rebuild it."
            fi
        }

        if [ "$NATIVE_BUILD_NEEDED" = 1 ] ; then
            NATIVE_BCACHED_DIR="$PACKAGE_WORKING_DIR/src/-"
            NATIVE_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_INSTALL_SHA"

            cat <<EOF
NATIVE_BCACHED_DIR = $NATIVE_BCACHED_DIR
NATIVE_INSTALL_DIR = $NATIVE_INSTALL_DIR
EOF

            (
                PACKAGE_BCACHED_DIR="$NATIVE_BCACHED_DIR"
                PACKAGE_INSTALL_DIR="$NATIVE_INSTALL_DIR"

                run install -d "$PACKAGE_BCACHED_DIR"

                if [ "$PACKAGE_BINBSTD" = 1 ] ; then
                    run cd "$PACKAGE_BSCRIPT_DIR"
                else
                    run cd "$PACKAGE_BCACHED_DIR"
                fi

                eval "
build_for_native() {
$PACKAGE_DO12345
}"

                [ "$DUMP_ENV" = 1 ] && {
                    run export -p
                    printf '\n'
                }

                BUILD_FOR_NATIVE=1

                build_for_native
            )

            [ -d "$NATIVE_INSTALL_DIR" ] && {
                printf '%s\n' "$PACKAGE_VERSION" > "$NATIVE_INSTALL_DIR/version.txt"
                run ln -s -r -f -T "$NATIVE_INSTALL_DIR" "$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_NAME"
            }
        else
            NATIVE_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_NAME"
        fi

        [ -d "$NATIVE_INSTALL_DIR" ] && {
            if [ -d  "$NATIVE_INSTALL_DIR/bin" ] ; then
                PATH="$NATIVE_INSTALL_DIR/bin:$PATH"
            fi

            if [ -d  "$NATIVE_INSTALL_DIR/sbin" ] ; then
                PATH="$NATIVE_INSTALL_DIR/sbin:$PATH"
            fi

            if [ -d          "$NATIVE_INSTALL_DIR/share/aclocal" ] ; then
                ACLOCAL_PATH="$NATIVE_INSTALL_DIR/share/aclocal:$ACLOCAL_PATH"
            fi
        }
    fi

    #########################################################################################
    #                               below is for target                                     #
    #########################################################################################

    step "prepare C/C++ toolchain for target build"

    export CC="$WRAPPER_TARGET_CC"
    export CXX="$WRAPPER_TARGET_CXX"
    export OBJC="$WRAPPER_TARGET_OBJC"
    export CPP="$WRAPPER_TARGET_CC -E"

    for TOOL in AS AR RANLIB LD NM STRIP SIZE STRINGS OBJDUMP OBJCOPY READELF ADDR2LINE
    do
        eval export "${TOOL}=\"\$${TOOL}_FOR_BUILD\""
    done

    #########################################################################################

    if [ "$CROSS_COMPILING" = 1 ] && [ "$TARGET_PLATFORM_NAME" != macos ] ; then
        export PROXIED_TARGET_CC="$(command -v clang)"    || abort 1 "command not found: clang"
        export PROXIED_TARGET_CXX="$(command -v clang++)" || abort 1 "command not found: clang++"
        export PROXIED_TARGET_OBJC="$PROXIED_TARGET_CC"

        step "prepare C/C++ sysroot for target build"

        export SYSROOT="$PPKG_SYSROOT/$TARGET_PLATFORM_SPEC"
        printf "%11s = %s\n" SYSROOT "$SYSROOT"

        if [ ! -f "$SYSROOT/ok" ] ; then
            __setup_sysroot
        fi
    else
        export PROXIED_TARGET_CC="$PROXIED_NATIVE_CC"
        export PROXIED_TARGET_CXX="$PROXIED_NATIVE_CXX"
        export PROXIED_TARGET_OBJC="$PROXIED_NATIVE_OBJC"
    fi

    #########################################################################################

    if [ "$CROSS_COMPILING" != 1 ] ; then
        case $TARGET_PLATFORM_NAME in
            netbsd)
                printf '%s\n' 'INPUT(-lc)'      > "$PACKAGE_WORKING_DIR/lib/libdl.a"
                printf '%s\n' 'INPUT(-lgcc_eh)' > "$PACKAGE_WORKING_DIR/lib/libgcc_s.a"
                ;;
            openbsd)
                # https://github.com/mesonbuild/meson/issues/5390
                printf '%s\n' 'INPUT(-lc)' > "$PACKAGE_WORKING_DIR/lib/libdl.a"
                printf '%s\n' 'INPUT(-lc)' > "$PACKAGE_WORKING_DIR/lib/librt.a"
                printf '%s\n' 'INPUT(-lc)' > "$PACKAGE_WORKING_DIR/lib/libcrypt.a"
                ;;
        esac
    fi

    #########################################################################################

    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        case $TARGET_PLATFORM_NAME in
            freebsd)
                if [ "$CROSS_COMPILING" != 1 ] ; then
                    printf 'INPUT(-lcompiler_rt -lgcc_eh)\n' > "$PACKAGE_WORKING_DIR/lib/libgcc_s.a"
                fi
                ;;
            netbsd)
                if [ "$CROSS_COMPILING" = 1 ] ; then
                    printf 'INPUT(%s/usr/lib/libstdc++.a -lgcc_s)\n' "$SYSROOT" >  "$PACKAGE_WORKING_DIR/lib/libstdc++.a"
                fi
                ;;
            linux)
                if [ "$TARGET_PLATFORM_VERS" = musl ] ; then
                    if [ "$TARGET_PLATFORM_ARCH" = riscv64 ] ; then
                        LIBC_FILEPATH="$("$CC" -print-file-name=libc.a)"
                        printf 'INPUT(%s -l:libgcc.a -l:libgcc_eh.a %s)\n' "$LIBC_FILEPATH" "$LIBC_FILEPATH" > "$PACKAGE_WORKING_DIR/lib/libc.a"
                        printf '%s\n' '!<arch>' > "$PACKAGE_WORKING_DIR/lib/libgcc_s.a"
                    else
                        printf '%s\n' 'INPUT(-l:libgcc_eh.a)' > "$PACKAGE_WORKING_DIR/lib/libgcc_s.a"
                    fi
                fi
        esac
    fi

    #########################################################################################

    [ -n "$RECURSIVE_DEPENDENT_PACKAGE_NAMES" ] && {
        if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
            step "copy dependent libraries to linker first search dir"

            for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
            do
                DEPENDENT_PACKAGE_LIBRARY_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME/lib"

                if [  -d "$DEPENDENT_PACKAGE_LIBRARY_DIR" ] ; then
                    find "$DEPENDENT_PACKAGE_LIBRARY_DIR" -maxdepth 1 -mindepth 1 -name 'lib*.a' -exec cp -L -v '{}' "$PACKAGE_WORKING_DIR/lib/" \;
                fi
            done
        fi
    }

    #########################################################################################

    [ "$ENABLE_CCACHE" = 1 ] && {
        step "setup ccache"

        run ln -sf "$CCACHE" "$PACKAGE_WORKING_DIR/bin/wrapper-target-cc"
        run ln -sf "$CCACHE" "$PACKAGE_WORKING_DIR/bin/wrapper-target-c++"

        ccache -s > "$PACKAGE_WORKING_DIR/ccache-s.txt"
    }

    #########################################################################################

    unset PPFLAGS
    unset CCFLAGS
    unset OCFLAGS
    unset XXFLAGS

    unset WRAPPER_TARGET_BASEFLAGS

    if [ "$TARGET_PLATFORM_NAME" = macos ] ; then
        LDFLAGS="-Wl,-search_paths_first"

        WRAPPER_TARGET_BASEFLAGS="-isysroot $SYSROOT -mmacosx-version-min=$TARGET_PLATFORM_VERS -arch $TARGET_PLATFORM_ARCH -Qunused-arguments -fno-common"
    else
        # https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
        LDFLAGS="-Wl,--as-needed -Wl,-z,muldefs -Wl,--allow-multiple-definition"

        if [ -n "$SYSROOT" ] ; then
            WRAPPER_TARGET_BASEFLAGS="--sysroot=$SYSROOT"
        fi

        if [ "$CROSS_COMPILING" = 1 ] ; then
            ENABLE_LTO=0

            if [ "$TARGET_PLATFORM_NAME" = linux ] ; then
                CLANG_TARGET="$TARGET_PLATFORM_ARCH-unknown-$TARGET_PLATFORM_NAME-$TARGET_PLATFORM_VERS"
            else
                CLANG_TARGET="$TARGET_PLATFORM_ARCH-unknown-$TARGET_PLATFORM_NAME"
            fi

            WRAPPER_TARGET_BASEFLAGS="--target=$CLANG_TARGET $WRAPPER_TARGET_BASEFLAGS"

            for x in c++/v1 g++
            do
                y="$SYSROOT/usr/include/$x"

                if [ -d "$y" ] ; then
                    PPFLAGS="$PPFLAGS -I$y"
                    XXFLAGS="$XXFLAGS -I$y"
                    break
                fi
            done

            if [ "$TARGET_PLATFORM_NAME" = freebsd ] ; then
                # https://github.com/llvm/llvm-project/issues/74917
                LDFLAGS="$LDFLAGS -fuse-ld=lld"
            fi
        fi
    fi

    ##############################################

    if [ "$DEBUG_CC" = 1 ] ; then
        WRAPPER_TARGET_BASEFLAGS="$WRAPPER_TARGET_BASEFLAGS -v"
    fi

    if [ "$DEBUG_LD" = 1 ] ; then
        LDFLAGS="$LDFLAGS -Wl,-v"
    fi

    ##############################################

    case $PROFILE in
        debug)
            CCFLAGS="$CCFLAGS -O0 -g"
            OCFLAGS="$OCFLAGS -g -O0"
            XXFLAGS="$XXFLAGS -O0 -g"
            ;;
        release)
            CCFLAGS="$CCFLAGS -Os"
            OCFLAGS="$OCFLAGS -Os"
            XXFLAGS="$XXFLAGS -Os"

            unset _U_NDEBUG_OPT_IS_SET

            for item in $PACKAGE_PPFLAGS
            do
                [ "$item" = '-UNDEBUG' ] && {
                    _U_NDEBUG_OPT_IS_SET=1
                    break
                }
            done

            if [ "$_U_NDEBUG_OPT_IS_SET" != 1 ] ; then
                PPFLAGS="$PPFLAGS -DNDEBUG"
            fi

            if [ -z "$ENABLE_LTO" ] || [ "$ENABLE_LTO" = 1 ] ; then
                LDFLAGS="$LDFLAGS -flto"
            fi

            if [ "$TARGET_PLATFORM_NAME" = macos ] ; then
                LDFLAGS="$LDFLAGS -Wl,-S"
            else
                case $ENABLE_STRIP in
                    all)   LDFLAGS="$LDFLAGS -Wl,-s" ;;
                    debug) LDFLAGS="$LDFLAGS -Wl,-S" ;;
                esac
            fi
    esac

    #case $TARGET_PLATFORM_NAME in
    #    netbsd)  LDFLAGS="$LDFLAGS -pthread" ;;
    #    openbsd) LDFLAGS="$LDFLAGS -pthread" ;;
    #esac

    #########################################################################################

    cd "$PACKAGE_WORKING_DIR"

    step "check if C compiler supports -Wno-error=unused-command-line-argument option"

    cat > test.c <<EOF
int main() {
    return 0;
}
EOF

    if "$CC" -Wno-error=unused-command-line-argument test.c 2>/dev/null ; then
        CCFLAGS="$CCFLAGS -Wno-error=unused-command-line-argument"
        success "YES"
    else
        error "NO"
    fi

    #########################################################################################

    step "check if C++ compiler supports -Wno-error=unused-command-line-argument option"

    cat > test.cc <<EOF
int main() {
    return 0;
}
EOF

    if "$CXX" -Wno-error=unused-command-line-argument test.cc 2>/dev/null ; then
        XXFLAGS="$XXFLAGS -Wno-error=unused-command-line-argument"
        success "YES"
    else
        error "NO"
    fi

    #########################################################################################

    PKG_CONFIG_PATH=

    ##################################################################################

    unset TARGET_INCLUDE_SEARCH_DIRS
    unset TARGET_LIBRARY_SEARCH_DIRS

    for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
    do
        DEPENDENT_PACKAGE_NAME_UNDERSCORE=$(printf '%s\n' "$DEPENDENT_PACKAGE_NAME" | tr '@+-.' '_')

        DEPENDENT_PACKAGE_INSTALL_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME"
        DEPENDENT_PACKAGE_INCLUDE_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/include"
        DEPENDENT_PACKAGE_LIBRARY_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/lib"

        eval "${DEPENDENT_PACKAGE_NAME_UNDERSCORE}_INSTALL_DIR='$DEPENDENT_PACKAGE_INSTALL_DIR'"
        eval "${DEPENDENT_PACKAGE_NAME_UNDERSCORE}_INCLUDE_DIR='$DEPENDENT_PACKAGE_INCLUDE_DIR'"
        eval "${DEPENDENT_PACKAGE_NAME_UNDERSCORE}_LIBRARY_DIR='$DEPENDENT_PACKAGE_LIBRARY_DIR'"

        if [ -d "$DEPENDENT_PACKAGE_INCLUDE_DIR" ] ; then
            TARGET_INCLUDE_SEARCH_DIRS="$TARGET_INCLUDE_SEARCH_DIRS:$DEPENDENT_PACKAGE_INCLUDE_DIR"
        fi

        if [ -d "$DEPENDENT_PACKAGE_LIBRARY_DIR" ] ; then
            TARGET_LIBRARY_SEARCH_DIRS="$TARGET_LIBRARY_SEARCH_DIRS:$DEPENDENT_PACKAGE_LIBRARY_DIR"
        fi

        for d in lib share
        do
            DEPENDENT_PACKAGE_PKGCONF_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/$d/pkgconfig"

            if [ -d "$DEPENDENT_PACKAGE_PKGCONF_DIR" ] ; then
                PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$DEPENDENT_PACKAGE_PKGCONF_DIR"
                break
            fi
        done

        DEPENDENT_PACKAGE_ACLOCAL_PATH="$DEPENDENT_PACKAGE_INSTALL_DIR/share/aclocal"

        if [ -d "$DEPENDENT_PACKAGE_ACLOCAL_PATH" ] ; then
            if [ -z "$ACLOCAL_PATH" ] ; then
                ACLOCAL_PATH="$DEPENDENT_PACKAGE_ACLOCAL_PATH"
            else
                ACLOCAL_PATH="$DEPENDENT_PACKAGE_ACLOCAL_PATH:$ACLOCAL_PATH"
            fi
        fi

        ###################################################################################

        # https://gi.readthedocs.io/en/latest/tools/g-ir-scanner.html#environment-variables
        if [ -d "$DEPENDENT_PACKAGE_INSTALL_DIR/share/gir-1.0" ] ; then
            if [ -z "$XDG_DATA_DIRS" ] ; then
                XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share"
            else
                XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share:$XDG_DATA_DIRS"
            fi
        fi

        # https://help.gnome.org/admin//system-admin-guide/2.32/mimetypes-database.html.en
        if [ -d "$DEPENDENT_PACKAGE_INSTALL_DIR/share/mime" ] ; then
            if [ -z "$XDG_DATA_DIRS" ] ; then
                XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share"
            else
                XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share:$XDG_DATA_DIRS"
            fi
        fi
    done

    TARGET_INCLUDE_SEARCH_DIRS="${TARGET_INCLUDE_SEARCH_DIRS#:}"
    TARGET_LIBRARY_SEARCH_DIRS="${TARGET_LIBRARY_SEARCH_DIRS#:}"

    #########################################################################################

    export PATH="$PACKAGE_WORKING_DIR/bin:$PATH"

    # https://www.gnu.org/software/automake/manual/html_node/Macro-Search-Path.html
    export ACLOCAL_PATH="$PACKAGE_WORKING_DIR/share/aclocal:$ACLOCAL_PATH"

    # https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
    export XDG_DATA_DIRS="$PACKAGE_WORKING_DIR/share/mime:$XDG_DATA_DIRS"

    export PKG_CONFIG_PATH="$PACKAGE_WORKING_DIR/lib/pkgconfig:$PKG_CONFIG_PATH"

    # override the default search directory (usually /usr/lib/pkgconfig:/usr/share/pkgconfig)
    export PKG_CONFIG_LIBDIR="$PACKAGE_WORKING_DIR/lib/pkgconfig"

    if [ "$DEBUG_PKG_CONFIG" = 1 ] ; then
        export PKG_CONFIG_DEBUG_SPEW='set'
    fi

    #########################################################################################

    PPFLAGS="-I$PACKAGE_INSTALLING_INC_DIR $PPFLAGS"
    LDFLAGS="-L$PACKAGE_INSTALLING_LIB_DIR $LDFLAGS"

    if [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        if [ "$TARGET_PLATFORM_NAME" != macos ] ; then
            LDFLAGS="-static-libgcc $LDFLAGS"
        fi

        LDFLAGS="-static-libstdc++ $LDFLAGS"
    fi

    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        # both --static and -static flag should be given.
        #  -static flag will be filtered out by libtool, libtool recognize this flag as prefer to link static library.
        # --static flag will be passed to the linker, although this flag was not documented, but it indeed works.
        LDFLAGS="-static --static -ffunction-sections -fdata-sections -Wl,--gc-sections $LDFLAGS"
        #-Wl,--no-dynamic-linker
    fi

    ##############################################################################

    export IFS=':'

    for d in $TARGET_INCLUDE_SEARCH_DIRS
    do
        PPFLAGS="$PPFLAGS -I$d"
    done

    for d in $TARGET_LIBRARY_SEARCH_DIRS
    do
        LDFLAGS="$LDFLAGS -L$d -Wl,-rpath,$d"
    done

    unset IFS

    ##############################################################################

    CCFLAGS="$CCFLAGS $PACKAGE_CCFLAGS"
    XXFLAGS="$XXFLAGS $PACKAGE_XXFLAGS"
    PPFLAGS="$PPFLAGS $PACKAGE_PPFLAGS"

    export   CFLAGS="$CCFLAGS"
    export CXXFLAGS="$XXFLAGS"
    export CPPFLAGS="$PPFLAGS"
    export  LDFLAGS="$LDFLAGS"

    export WRAPPER_TARGET_LDFLAGS="-L$PACKAGE_INSTALLING_LIB_DIR"
    export WRAPPER_TARGET_CCFLAGS="$WRAPPER_TARGET_BASEFLAGS"
    export WRAPPER_TARGET_CXXFLAGS="$WRAPPER_TARGET_CCFLAGS"
    export WRAPPER_TARGET_OBJCFLAGS="$WRAPPER_TARGET_CCFLAGS"

    for item in $PACKAGE_DEP_LIB
    do
        case $item in
            -l*);;
            *)  item="$(pkg-config --libs-only-l "$item")"
        esac

        WRAPPER_TARGET_LDFLAGS="$WRAPPER_TARGET_LDFLAGS $item"
    done

    for item in $PACKAGE_LDFLAGS
    do
        case $item in
            -p*) item="$(pkg-config --libs-only-l "${item#-p}")" ;;
        esac

        WRAPPER_TARGET_LDFLAGS="$WRAPPER_TARGET_LDFLAGS $item"
    done

    if [ "$TARGET_PLATFORM_NAME" = linux ] && [ "$TARGET_PLATFORM_VERS" = musl ] ; then
        if [ -n "$PACKAGE_DEP_PKG_FOR_MUSL" ] ; then
            WRAPPER_TARGET_LDFLAGS="$WRAPPER_TARGET_LDFLAGS -Wl,--whole-archive"

            for item in $PACKAGE_DEP_PKG_FOR_MUSL
            do
                WRAPPER_TARGET_LDFLAGS="$WRAPPER_TARGET_LDFLAGS -l:$item.a"
            done

            WRAPPER_TARGET_LDFLAGS="$WRAPPER_TARGET_LDFLAGS -Wl,--no-whole-archive"
        fi
    fi

    #########################################################################################

    if [ "$PACKAGE_USE_BSYSTEM_CMAKE" = 1 ] ; then
        # https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html#manual:cmake-env-variables(7)

        unset CMAKE_PREFIX_PATH
        unset CMAKE_APPLE_SILICON_PROCESSOR
        unset CMAKE_BUILD_PARALLEL_LEVEL
        unset CMAKE_BUILD_TYPE
        unset CMAKE_CONFIGURATION_TYPES
        unset CMAKE_CONFIG_TYPE
        unset CMAKE_EXPORT_COMPILE_COMMANDS
        unset CMAKE_GENERATOR
        unset CMAKE_GENERATOR_INSTANCE
        unset CMAKE_GENERATOR_PLATFORM
        unset CMAKE_GENERATOR_TOOLSET
        unset CMAKE_INSTALL_MODE
        unset CMAKE_C_COMPILER_LAUNCHER
        unset CMAKE_C_LINKER_LAUNCHER
        unset CMAKE_CXX_COMPILER_LAUNCHER
        unset CMAKE_CXX_LINKER_LAUNCHER
        unset CMAKE_MSVCIDE_RUN_PATH
        unset CMAKE_NO_VERBOSE
        unset CMAKE_OSX_ARCHITECTURES
        unset CMAKE_TOOLCHAIN_FILE
        unset DESTDIR
        unset CTEST_INTERACTIVE_DEBUG_MODE
        unset CTEST_OUTPUT_ON_FAILURE
        unset CTEST_PARALLEL_LEVEL
        unset CTEST_PROGRESS_OUTPUT
        unset CTEST_USE_LAUNCHERS_DEFAULT
        unset DASHBOARD_TEST_FROM_CTEST

        # https://cmake.org/cmake/help/latest/envvar/CMAKE_BUILD_PARALLEL_LEVEL.html
        export CMAKE_BUILD_PARALLEL_LEVEL="$BUILD_NJOBS"

        # https://cmake.org/cmake/help/latest/envvar/CMAKE_GENERATOR.html
        if [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] ; then
            export CMAKE_GENERATOR='Ninja'
        else
            export CMAKE_GENERATOR='Unix Makefiles'
        fi

        # https://cmake.org/cmake/help/latest/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.html
        if [ "$EXPORT_COMPILE_COMMANDS_JSON" = 1 ] ; then
            export CMAKE_EXPORT_COMPILE_COMMANDS=ON
        else
            export CMAKE_EXPORT_COMPILE_COMMANDS=OFF
        fi

        case $PROFILE in
            debug)   CMAKE_BUILD_TYPE=Debug   ;;
            release) CMAKE_BUILD_TYPE=Release ;;
        esac

        if [ "$VERBOSE_CMAKE" = 1 ] ; then
            CMAKE_VERBOSE_MAKEFILE=OFF
            CMAKE_COLOR_MAKEFILE=OFF
        else
            CMAKE_VERBOSE_MAKEFILE=ON
            CMAKE_COLOR_MAKEFILE=ON
        fi

        # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_DEBUG_MODE.html
        if [ "$DEBUG_CMAKE" = 1 ] ; then
            CMAKE_FIND_DEBUG_MODE=ON
        else
            CMAKE_FIND_DEBUG_MODE=OFF
        fi

        CMAKE_TOOLCHAIN_FILE="$PACKAGE_WORKING_DIR/toolchain.cmake"

        # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_ROOT_PATH.html

        CMAKE_FIND_ROOT_PATH="$PACKAGE_WORKING_DIR"

        for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
        do
            DEPENDENT_PACKAGE_INSTALL_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME"

            if [ -z "$CMAKE_FIND_ROOT_PATH" ] ; then
                CMAKE_FIND_ROOT_PATH="$DEPENDENT_PACKAGE_INSTALL_DIR"
            else
                CMAKE_FIND_ROOT_PATH="$CMAKE_FIND_ROOT_PATH;$DEPENDENT_PACKAGE_INSTALL_DIR"
            fi
        done

        if [ -n "$SYSROOT" ] ; then
            if [ -z "$CMAKE_FIND_ROOT_PATH" ] ; then
                CMAKE_FIND_ROOT_PATH="$SYSROOT"
            else
                CMAKE_FIND_ROOT_PATH="$CMAKE_FIND_ROOT_PATH;$SYSROOT"
            fi
        fi
    fi

    #########################################################################################

    if [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] ; then
        # https://github.com/rust-lang/rust/issues/89626
        if [ "$RUST_TARGET" = 'aarch64-unknown-linux-musl' ] ; then
            CFLAGS="$CFLAGS -mno-outline-atomics"
        fi

        # https://docs.rs/backtrace/latest/backtrace/
        export RUST_BACKTRACE=1

        export CARGO_BUILD_JOBS="$BUILD_NJOBS"

        #########################################################################

        # this environment variable is not defined by Rust, but it is widely used by a large number of third-party projects.
        export RUST_TARGET

        if [ "$CROSS_COMPILING" = 1 ] ; then
            case $TARGET_PLATFORM_NAME in
                linux)
                    case $TARGET_PLATFORM_VERS in
                        glibc) XX=gnu  ;;
                        musl)  XX=musl ;;
                        *)     XX=
                    esac

                    case $TARGET_PLATFORM_ARCH in
                        ppc64le) RUST_TARGET="powerpc64le-unknown-linux-$XX" ;;
                        riscv64) RUST_TARGET="riscv64gc-unknown-linux-$XX"  ;;
                        *)       RUST_TARGET="$TARGET_PLATFORM_ARCH-unknown-linux-$XX" ;;
                    esac
                    ;;
                macos)
                    case $TARGET_PLATFORM_ARCH in
                        x86_64) RUST_TARGET='x86_64-apple-darwin'  ;;
                        arm64)  RUST_TARGET='aarch64-apple-darwin' ;;
                    esac
                    ;;
                *)
                    case $TARGET_PLATFORM_ARCH in
                        amd64)  RUST_TARGET="x86_64-unknown-$TARGET_PLATFORM_NAME" ;;
                        *)      RUST_TARGET="$TARGET_PLATFORM_ARCH-unknown-$TARGET_PLATFORM_NAME"  ;;
                    esac
            esac

            RUST_TARGET_FOR_BUILD="$(rustc -vV | sed -n '/host: /p' | cut -c7- | tr 'a-z-' 'A-Z_')"

            # https://doc.rust-lang.org/cargo/reference/config.html#environment-variables
            # https://doc.rust-lang.org/cargo/reference/environment-variables.html
            export "CARGO_TARGET_${RUST_TARGET_FOR_BUILD}_AR"="$AR_FOR_BUILD"
            export "CARGO_TARGET_${RUST_TARGET_FOR_BUILD}_LINKER"="$CC_FOR_BUILD"

            # https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg
            RUSTFLAGS_FOR_BUILD="-Clinker=$CC_FOR_BUILD"

            for LDARG in $LDFLAGS_FOR_BUILD
            do
                RUSTFLAGS_FOR_BUILD="$RUSTFLAGS_FOR_BUILD -Clink-arg=$LDARG"
            done

            [ "$PACKAGE_DEP_AUX_LIBZ" = 1 ] && {
                RUSTFLAGS_FOR_BUILD="$RUSTFLAGS_FOR_BUILD -L native=$NATIVE_PACKAGE_INSTALLED_ROOT/libz"
            }

            export "CARGO_TARGET_${RUST_TARGET_FOR_BUILD}_RUSTFLAGS"="$RUSTFLAGS_FOR_BUILD"

            # https://libraries.io/cargo/pkg-config
            # https://crates.io/crates/pkg-config
            # https://docs.rs/pkg-config/latest/pkg_config/
            # https://github.com/rust-lang/pkg-config-rs
            export HOST_PKG_CONFIG_PATH="$PKG_CONFIG_PATH_FOR_BUILD"
            export HOST_PKG_CONFIG_LIBDIR="$PPKG_CORE_DIR/lib/pkgconfig"

            # https://libraries.io/cargo/cc
            # https://crates.io/crates/cc
            # https://docs.rs/cc/latest/cc/
            # https://github.com/alexcrichton/cc-rs
            export HOST_CC="$CC_FOR_BUILD"
            export HOST_CFLAGS="$CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD"

            export HOST_CXX="$CXX_FOR_BUILD"
            export HOST_CXXFLAGS="$CXXFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD"

            export HOST_AR="$AR_FOR_BUILD"

            #########################################################################

            # https://docs.rs/openssl/latest/openssl/
            [ "$PACKAGE_DEP_AUX_LIBOPENSSL" = 1 ] && {
                eval export "${RUST_TARGET_FOR_BUILD}_OPENSSL_DIR='$NATIVE_PACKAGE_INSTALLED_ROOT/libopenssl'"
                eval export "${RUST_TARGET_FOR_BUILD}_OPENSSL_NO_VENDOR=1"
                export OPENSSL_NO_VENDOR=1
            }
        else
            RUST_TARGET="$(rustc -vV | sed -n '/host: /p' | cut -c7-)"
        fi

        #########################################################

        RUST_TARGET_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$RUST_TARGET" | tr a-z A-Z | tr - _)

        # https://doc.rust-lang.org/cargo/reference/config.html#environment-variables
        # https://doc.rust-lang.org/cargo/reference/environment-variables.html
        export "CARGO_TARGET_${RUST_TARGET_UPPERCASE_UNDERSCORE}_AR"="$AR"
        export "CARGO_TARGET_${RUST_TARGET_UPPERCASE_UNDERSCORE}_LINKER"="$CC"

        #########################################################

        # https://doc.rust-lang.org/rustc/command-line-arguments.html
        # https://doc.rust-lang.org/rustc/codegen-options/index.html
        export RUSTFLAGS="-Clinker=$CC -L native=$PACKAGE_INSTALLING_LIB_DIR"

        if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
            if [ "$TARGET_PLATFORM_NAME" != linux ] ; then
                if [ "$CROSS_COMPILING" = 1 ] ; then
                    LIBCLANG_RT_BUILTINS_FILEPATH="$("$CC" -print-libgcc-file-name)"
                    RUSTFLAGS="$RUSTFLAGS -Clink-arg=$LIBCLANG_RT_BUILTINS_FILEPATH"
                fi
            fi
        fi

        for LDFLAG in $LDFLAGS
        do
            RUSTFLAGS="$RUSTFLAGS -Clink-arg=$LDFLAG"
        done

        #########################################################################

        for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
        do
            case $DEPENDENT_PACKAGE_NAME in
                openssl@1.1)
                    # https://docs.rs/openssl/latest/openssl/
                    export OPENSSL_DIR="$openssl_1_1_INSTALL_DIR"

                    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/sfackler/rust-openssl/blob/master/openssl-sys/build/main.rs
                        export OPENSSL_STATIC=1
                        export OPENSSL_NO_VENDOR=1
                    fi
                    ;;
                libopenssl)
                    # https://docs.rs/openssl/latest/openssl/
                    export OPENSSL_DIR="$libopenssl_INSTALL_DIR"

                    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/sfackler/rust-openssl/blob/master/openssl-sys/build/main.rs
                        export OPENSSL_STATIC=1
                        export OPENSSL_NO_VENDOR=1
                    fi
                    ;;
                libssh2)
                    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/alexcrichton/ssh2-rs/blob/master/libssh2-sys/build.rs
                        export LIBSSH2_SYS_USE_PKG_CONFIG=1
                    fi
                    ;;
                libgit2)
                    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/rust-lang/git2-rs/blob/master/libgit2-sys/build.rs
                        export LIBGIT2_NO_VENDOR=1
                        export LIBGIT2_SYS_USE_PKG_CONFIG=1
                    fi
                    ;;
                libz|zlib)
                    if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/rust-lang/libz-sys/blob/main/build.rs
                        export LIBZ_SYS_STATIC=1
                    fi
                    ;;
            esac
        done

        #########################################################

        # https://libraries.io/cargo/cc
        # https://crates.io/crates/cc
        # https://docs.rs/cc/latest/cc/
        # https://github.com/alexcrichton/cc-rs

        if [ "$CROSS_COMPILING" = 1 ] ; then
            export HOST_CC="$CC_FOR_BUILD"
            export HOST_CFLAGS="$CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD"

            export HOST_CXX="$CXX_FOR_BUILD"
            export HOST_CXXFLAGS="$CXXFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD"

            export HOST_AR="$AR_FOR_BUILD"
        else
            export HOST_CC="$CC"
            export HOST_CFLAGS="$CFLAGS $CPPFLAGS"

            export HOST_CXX="$CXX"
            export HOST_CXXFLAGS="$CXXFLAGS $CPPFLAGS"

            export HOST_AR="$AR"
        fi

        export TARGET_CC="$CC"
        export TARGET_CFLAGS="$CFLAGS $CPPFLAGS"

        export TARGET_CXX="$CXX"
        export TARGET_CXXFLAGS="$CXXFLAGS $CPPFLAGS"

        export TARGET_AR="$AR"


        # https://libraries.io/cargo/pkg-config
        # https://crates.io/crates/pkg-config
        # https://docs.rs/pkg-config/latest/pkg_config/
        # https://github.com/rust-lang/pkg-config-rs
        # export TARGET_PKG_CONFIG_ALLOW_CROSS=1


        # https://libraries.io/cargo/cmake
        # https://crates.io/crates/cmake
        # https://docs.rs/cmake/latest/cmake/
        # https://github.com/alexcrichton/cmake-rs
        # this variable is not motioned in their document. you must read the source code of cmake-rs crate.
        # export TARGET_CMAKE_TOOLCHAIN_FILE="$TARGET_WORKING_DIR/toolchain.cmake"


    fi

    #########################################################################################

    if [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] ; then
        # https://golang.org/doc/install/source#environment

        if [ "$CROSS_COMPILING" = 1 ] ; then
            case $TARGET_PLATFORM_NAME in
                dragonflybsd) export GOOS='dragonfly' ;;
                macos)        export GOOS='darwin'    ;;
                *)            export GOOS="$TARGET_PLATFORM_NAME"
            esac

            case $TARGET_PLATFORM_ARCH in
                x86_64)       export GOARCH='amd64'   ;;
                loongarch64)  export GOARCH='loong64' ;;
                *)            export GOARCH="$TARGET_PLATFORM_ARCH"
            esac
        else
            unset GOOS
            unset GOARCH
        fi

        export GO111MODULE='auto'

        # https://pkg.go.dev/cmd/cgo
        export CGO_ENABLED=0
        export CGO_CFLAGS="$CFLAGS"
        export CGO_CXXFLAGS="$CXXFLAGS"
        export CGO_CPPFLAGS="$CPPFLAGS"
        export CGO_LDFLAGS="$LDFLAGS"
    fi

    #########################################################################################

    step "dopatch for target"

    run cd "$PACKAGE_BSCRIPT_DIR"

    [ -f "$PACKAGE_INSTALLING_FIX_DIR/index" ] && {
        for LINE in $(cat "$PACKAGE_INSTALLING_FIX_DIR/index")
        do
            FILE="$(printf '%s\n' "$LINE" | cut -d '|' -f1)"
            OPTS="$(printf '%s\n' "$LINE" | cut -d '|' -f2)"
            [ -z "$OPTS" ] && OPTS='-p1'
            run "patch $OPTS < $PACKAGE_INSTALLING_FIX_DIR/$FILE"
        done
    }

    [ -n "$PACKAGE_DOPATCH" ] && {
        eval "
dopatch() {
$PACKAGE_DOPATCH
}"
        dopatch
    }

    # https://github.com/golang/go/issues/65568
    [ -f go.mod ] && gsed -i 's|^go 1.22$|go 1.22.0|' go.mod

    #########################################################################################

    cd "$PACKAGE_BSCRIPT_DIR"

    case $PACKAGE_BSYSTEM_MASTER in
        autogen)
            if [ -f configure ] ; then
                CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP="$(stat --format=%Y configure)"

                if [ -z "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" ] ; then
                    run NOCONFIGURE=yes ./autogen.sh
                elif [ "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" -lt "$TIMESTAMP_UNIX" ] ; then
                    run NOCONFIGURE=yes ./autogen.sh
                fi
            else
                run NOCONFIGURE=yes ./autogen.sh
            fi
            ;;
        autotools)
            if [ -f configure ] ; then
                CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP="$(stat --format=%Y configure)"

                if [ -z "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" ] ; then
                    run autoreconf -ivf
                elif [ "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" -lt "$TIMESTAMP_UNIX" ] ; then
                    run autoreconf -ivf
                fi
            else
                run autoreconf -ivf
            fi
            ;;
    esac

    #########################################################################################

    {
        [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] ||
        [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] ||
        [ "$PACKAGE_USE_BSYSTEM_CONFIGURE" = 1 ]
    } && {
        step "update config.{sub,guess}"
        __update_config_sub_guess
    }

    #########################################################################################

    [ -n "$PACKAGE_PREPARE" ] && {
        step "prepare for target"

        eval "
    prepare() {
$PACKAGE_PREPARE
}"
        prepare
    }

    #########################################################################################

    step "install for target"

    if [ "$PACKAGE_BINBSTD" = 1 ] ; then
        run cd "$PACKAGE_BSCRIPT_DIR"
    else
        run cd "$PACKAGE_BCACHED_DIR"
    fi

    if [        -d "$PACKAGE_INSTALL_DIR" ] ; then
        run rm -rf "$PACKAGE_INSTALL_DIR"
    fi

    [ "$DUMP_ENV" = 1 ] && {
        run export -p
        echo
    }

    eval "
dobuild() {
$PACKAGE_DOBUILD
}"

    dobuild

    #########################################################################################

    cat > "$PACKAGE_WORKING_DIR/toolchain-native.sh" <<EOF
     CC_FOR_BUILD='$CC_FOR_BUILD'
   OBJC_FOR_BUILD='$OBJC_FOR_BUILD'
    CXX_FOR_BUILD='$CXX_FOR_BUILD'
     AS_FOR_BUILD='$AS_FOR_BUILD'
     AR_FOR_BUILD='$AR_FOR_BUILD'
 RANLIB_FOR_BUILD='$RANLIB_FOR_BUILD'
     LD_FOR_BUILD='$LD_FOR_BUILD'
     NM_FOR_BUILD='$NM_FOR_BUILD'
   SIZE_FOR_BUILD='$SIZE_FOR_BUILD'
  STRIP_FOR_BUILD='$STRIP_FOR_BUILD'
STRINGS_FOR_BUILD='$STRINGS_FOR_BUILD'
OBJDUMP_FOR_BUILD='$OBJDUMP_FOR_BUILD'
OBJCOPY_FOR_BUILD='$OBJCOPY_FOR_BUILD'
READELF_FOR_BUILD='$READELF_FOR_BUILD'
SYSROOT_FOR_BUILD='$SYSROOT_FOR_BUILD'

CCFLAGS_FOR_BUILD='$CCFLAGS_FOR_BUILD'
LDFLAGS_FOR_BUILD='$LDFLAGS_FOR_BUILD'
EOF

    cat > "$PACKAGE_WORKING_DIR/toolchain-target.sh" <<EOF
     CC='$CC'
   OBJC='$OBJC'
    CXX='$CXX'
     AS='$AS'
     AR='$AR'
 RANLIB='$RANLIB'
     LD='$LD'
     NM='$NM'
   SIZE='$SIZE'
  STRIP='$STRIP'
STRINGS='$STRINGS'
OBJDUMP='$OBJDUMP'
OBJCOPY='$OBJCOPY'
READELF='$READELF'
SYSROOT='$SYSROOT'

CCFLAGS='$CCFLAGS'
LDFLAGS='$LDFLAGS'
EOF

    #########################################################################################

    [   -d "$PACKAGE_INSTALL_DIR" ] || abort 1 "nothing was installed."

    step "change to the installed directory"
    run cd "$PACKAGE_INSTALL_DIR"

    [ -z "$(ls)" ]                  && abort 1 "nothing was installed."

    #########################################################################################

    [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && {
        run rm -f .crates.toml
        run rm -f .crates2.json
    }

    #########################################################################################

    for item in $PACKAGE_WRAPPER
    do
        S="${item%'|'*}"
        T="${item#*'|'}"

        wfetch "https://raw.githubusercontent.com/leleliu008/ppkg-formula-repository-official-core/refs/heads/master/wrappers/$S" --no-buffer
        run mv "$S" "$T"
    done

    #########################################################################################

    [ -n "$PACKAGE_DOTWEAK" ] && {
        step "dotweak"

        cd "$PACKAGE_INSTALL_DIR"

        eval "
dotweak() {
$PACKAGE_DOTWEAK
}"
        dotweak
    }

    #########################################################################################

    __tweak_pc_files

    #########################################################################################

    run cd "$PACKAGE_INSTALL_DIR"

    if [ -d lib ] ; then
        # https://www.linuxfromscratch.org/blfs/view/stable-systemd/introduction/la-files.html
        # remove Libtool Archive (.la) files
        find -L lib -maxdepth 1 -mindepth 1 -type f -name '*.la' -exec rm -v {} +
    fi

    #########################################################################################

    run install -d .ppkg/dependencies/lib/
    run install -d .ppkg/dependencies/sys/

    #########################################################################################

    step "docheck"

    unset FILES_NEED_TO_BE_SET_RPATH

    if [ "$TARGET_PLATFORM_NAME" = macos ] ; then
        __check_mach_o_files

        [ -n "$FILES_NEED_TO_BE_SET_RPATH" ] && {
            step "set rpath for executables"

            KVs="$(printf '%s\n' "$FILES_NEED_TO_BE_SET_RPATH" | sort | uniq)"

            for KV in $KVs
            do
                K="${KV%'|'*}"
                V="${KV#*'|'}"

                [ "$V" = 1 ] && V='.ppkg/dependencies/lib'

                RELATIVE_PATH="$(realpath -m --relative-to="${K%/*}" "$V")"

                run install_name_tool -add_rpath "@executable_path/$RELATIVE_PATH" "$K" || true
            done
        }
    else
        PATCHELF="$(command -v patchelf)"

        __check_elf_files

        find .ppkg/dependencies/lib -type f -exec "$PATCHELF" --set-rpath '$ORIGIN' {} \;

        [ -n "$FILES_NEED_TO_BE_SET_RPATH" ] && {
            step "set rpath for ELF files"

            KVs="$(printf '%s\n' "$FILES_NEED_TO_BE_SET_RPATH" | sort | uniq)"

            for KV in $KVs
            do
                K="${KV%'|'*}"
                V="${KV#*'|'}"

                [ "$V" = 1 ] && V='.ppkg/dependencies/lib'

                RELATIVE_PATH="$(realpath -m --relative-to="${K%/*}" "$V")"

                run "$PATCHELF" --add-rpath "'\$ORIGIN/$RELATIVE_PATH'" "$K"
            done
        }
    fi

    #########################################################################################

    RMDIR_IF_EMPTY="$PPKG_CORE_DIR/rmdir-if-empty"

    run "$RMDIR_IF_EMPTY" .ppkg/dependencies/lib/
    run "$RMDIR_IF_EMPTY" .ppkg/dependencies/sys/
    run "$RMDIR_IF_EMPTY" .ppkg/dependencies/

    #########################################################################################

    step "generate MANIFEST.txt"
    find -not -path . -a -not -path ./.ppkg -a -not -path './.ppkg/*' -printf '%y|%P\n' > .ppkg/MANIFEST.txt

    #########################################################################################

    run cd .ppkg

    #########################################################################################

    run mv "$PACKAGE_WORKING_DIR/toolchain-native.sh" .
    run mv "$PACKAGE_WORKING_DIR/toolchain-target.sh" .

    #########################################################################################

    for item in 'FAQ*' 'TODO*' 'NEWS*' 'THANKS*' 'README*' 'COPYING*' 'LICENSE*' 'AUTHORS*' 'CHANGES*' 'CHANGELOG*' 'CONTRIBUTORS*' 'CONTRIBUTING*'
    do
        find -L "$PACKAGE_INSTALLING_SRC_DIR" -mindepth 1 -maxdepth 1 -type f -iname "$item" -exec cp -L {} . \;
    done

    #########################################################################################

    [ -n "$PACKAGE_DEP_PKG" ] && {
        step "install dependency graph files"

        run mv "$PACKAGE_WORKING_DIR/dependencies.*" .

        step "install dependency formulas"

        install -d dependencies/

        for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
        do
            cp "$SESSION_DIR/$DEPENDENT_PACKAGE_NAME.yml" dependencies/
        done
    }

    #########################################################################################

    for dir in "$PACKAGE_BCACHED_DIR" "$PACKAGE_BSCRIPT_DIR"
    do
        if [ -f "$dir/config.log" ] ; then
            mv  "$dir/config.log" .
        fi
        if [ -f "$dir/compile_commands.json" ] ; then
            mv  "$dir/compile_commands.json" .
        fi
    done

    #########################################################################################

    step "generate RECEIPT.yml"

    cp "$PACKAGE_FORMULA_FILEPATH" RECEIPT.yml

    gsed -i '/^#src-url: dir:/d' RECEIPT.yml

    gsed -i "1i pkgname: $PACKAGE_NAME" RECEIPT.yml

    grep -q '^pkgtype: ' RECEIPT.yml || gsed -i "/^pkgname:/a pkgtype: $PACKAGE_PKGTYPE" RECEIPT.yml
    grep -q '^version: ' RECEIPT.yml || gsed -i "/^pkgtype:/a version: $PACKAGE_VERSION" RECEIPT.yml
    grep -q '^web-url: ' RECEIPT.yml || gsed -i "/^summary:/a web-url: $PACKAGE_GIT_URL" RECEIPT.yml
    grep -q '^git-url: ' RECEIPT.yml || gsed -i "/^web-url:/a git-url: $PACKAGE_GIT_URL" RECEIPT.yml
    grep -q '^bsystem: ' RECEIPT.yml || gsed -i "/^install:/i bsystem: $PACKAGE_BSYSTEM" RECEIPT.yml
    grep -q '^binbstd: ' RECEIPT.yml || gsed -i "/^bsystem:/a binbstd: $PACKAGE_BINBSTD" RECEIPT.yml
    grep -q '^parallel: ' RECEIPT.yml || printf "parallel: %s\n" "$PACKAGE_SUPPORT_BUILD_IN_PARALLEL" >> RECEIPT.yml

    [ -n "$PACKAGE_GIT_SHA" ] && {
        grep -q '^git-sha: ' RECEIPT.yml || {
            gsed -i "/^git-url:/a git-sha: $PACKAGE_GIT_SHA" RECEIPT.yml
        }

        grep -q '^git-sha: ' RECEIPT.yml || {
            gsed -i "3i git-sha: $PACKAGE_GIT_SHA" RECEIPT.yml
        }
    }

    [ -n "$PACKAGE_DEP_UPP" ] && {
        if grep -q '^dep-upp: ' RECEIPT.yml ; then
            gsed -i "/^dep-upp: /c dep-upp: $PACKAGE_DEP_UPP" RECEIPT.yml
        else
            gsed -i "/^bsystem: /i dep-upp: $PACKAGE_DEP_UPP" RECEIPT.yml
        fi
    }

    cat >> RECEIPT.yml <<EOF
profile: $PROFILE
builtfor: $TARGET_PLATFORM_SPEC
builtby: ppkg-$PPKG_VERSION
builtat: $TIMESTAMP_UNIX
builton:
    os-arch: $NATIVE_PLATFORM_ARCH
    os-kind: $NATIVE_PLATFORM_KIND
    os-type: $NATIVE_PLATFORM_TYPE
    os-libc: $NATIVE_PLATFORM_LIBC
    os-code: $NATIVE_PLATFORM_CODE
    os-name: $NATIVE_PLATFORM_NAME
    os-vers: $NATIVE_PLATFORM_VERS
    os-ncpu: $NATIVE_PLATFORM_NCPU
    os-euid: $NATIVE_PLATFORM_EUID
    os-egid: $NATIVE_PLATFORM_EGID
EOF

    if [ "$NATIVE_PLATFORM_TYPE" = linux ] ; then
        if command -v getconf > /dev/null ; then
            NATIVE_PLATFORM_LIBC_VERSION="$(getconf GNU_LIBC_VERSION | cut -d ' ' -f2)"
            if [ -n "$NATIVE_PLATFORM_LIBC_VERSION" ] ; then
                gsed -i "/os-libc: /s|$|-$NATIVE_PLATFORM_LIBC_VERSION|" RECEIPT.yml
            fi
        fi
    fi

    #########################################################################################

    step "generate index"
    run cd "$PPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC"
    run ln -s -f -T "$PACKAGE_INSTALL_SHA" "$PACKAGE_NAME"

    #########################################################################################

    step "show installed files in tree-like format"
    run tree --dirsfirst -a "$PACKAGE_INSTALL_DIR"

    #########################################################################################

    [ "$ENABLE_CCACHE" = 1 ] && {
        step "show ccache statistics summary"
        note "Before Build:"
        run  cat "$PACKAGE_WORKING_DIR/ccache-s.txt"
        note "After  Build:"
        run  ccache -s
    }

    [ "$REQUEST_TO_KEEP_SESSION_DIR" != 1 ] && {
        step "delete the working directory"
        run rm -rf "$PACKAGE_WORKING_DIR"
    }

    #########################################################################################

    printf '\n%b\n' "${COLOR_PURPLE}✅️  ${COLOR_OFF}${COLOR_GREEN}${1} was successfully installed.${COLOR_OFF}${COLOR_PURPLE}${COLOR_OFF}"

    if [ -n "$PACKAGE_CAVEATS" ] ; then
        printf '\n%b\n' "${COLOR_YELLOW}⚠️  Caveats:${COLOR_OFF}\n\n$PACKAGE_CAVEATS" >&2
    fi
}

__check_elf_files() {
    CHECKER="$PPKG_CORE_DIR/check-if-has-dynamic-section"

    find -type f -printf '%P\n' > files.txt

    while read -r FILEPATH
    do
        "$CHECKER" "$FILEPATH" || continue

        [ -w "$FILEPATH" ] || run chmod +w "$FILEPATH"

        run "$PATCHELF" --remove-rpath "$FILEPATH"

        __check_DT_NEEDED "$FILEPATH"
    done < files.txt

    rm files.txt
}

# __check_DT_NEEDED <ELF-FILE-PATH>
  __check_DT_NEEDED() {
    X="$(printf '%s\n' "$1" | tr / _)"
    Y="$PACKAGE_WORKING_DIR/map/$X"

    if [ -f "$Y" ] ; then
        return 0
    else
        touch "$Y"
    fi

    NEEDED_SHARED_LIBRARY_FILENAMEs="$("$PPKG_CORE_DIR/print-needed" "$1")"

    for NEEDED_SHARED_LIBRARY_FILENAME in $NEEDED_SHARED_LIBRARY_FILENAMEs
    do
        NEEDED_SHARED_LIBRARY_FILEPATH=

        case $1 in
            /*) ;;
            *)
                if [ -d lib ] ; then
                    NEEDED_SHARED_LIBRARY_FILEPATH="lib/$NEEDED_SHARED_LIBRARY_FILENAME"

                    [ -f "$NEEDED_SHARED_LIBRARY_FILEPATH" ] || {
                        unset NEEDED_SHARED_LIBRARY_FILEPATH
                        NEEDED_SHARED_LIBRARY_FILEPATH="$(find -L lib -type f -name "$NEEDED_SHARED_LIBRARY_FILENAME" -print -quit)"
                    }

                    [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] && {
                        FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|${NEEDED_SHARED_LIBRARY_FILEPATH%/*}"
                    }
                fi
        esac

        #####################################################

        NEEDED_UNKOWN=

        case "${NEEDED_SHARED_LIBRARY_FILENAME%.so*}" in
            libc)
                ;;
            libm)
                ;;
            librt)
                ;;
            libdl)
                ;;
            libomp)
                ;;
            libc++)
                ;;
            libstdc++)
                ;;
            libasan)
                ;;
            libmvec)
                ;;
            libutil)
                ;;
            libresolv)
                ;;
            libpthread)
                ;;
            libgomp)
                ;;
            libgfortran)
                ;;
            libgcc_s)
                ;;
            libclang_rt.*)
                ;;
            libc.musl-*)
                ;;
            ld-linux-*)
                ;;
            libtinfo)
                ;;
            *)  NEEDED_UNKOWN=1
        esac

        if [ -z "$NEEDED_UNKOWN" ] ; then
            F=".ppkg/dependencies/sys/$NEEDED_SHARED_LIBRARY_FILENAME"

            if [ ! -f "$F" ] ; then
                touch "$F"
            fi

            continue
        fi

        #####################################################

        if [ -z "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then
            if [ -n "$RECURSIVE_DEPENDENT_PACKAGE_NAMES" ] ; then
                for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
                do
                    NEEDED_SHARED_LIBRARY_ROOT_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME/lib"

                    [ -d "$NEEDED_SHARED_LIBRARY_ROOT_DIR" ] || continue

                    NEEDED_SHARED_LIBRARY_FILEPATH="$NEEDED_SHARED_LIBRARY_ROOT_DIR/$NEEDED_SHARED_LIBRARY_FILENAME"

                    [ -f "$NEEDED_SHARED_LIBRARY_FILEPATH" ] || {
                        unset NEEDED_SHARED_LIBRARY_FILEPATH
                        NEEDED_SHARED_LIBRARY_FILEPATH="$(find -L "$NEEDED_SHARED_LIBRARY_ROOT_DIR" -type f -name "$NEEDED_SHARED_LIBRARY_FILENAME" -print -quit)"
                    }

                    [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] && {
                        case $1 in
                            /*) ;;
                            *)  FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|1"
                        esac

                        F=".ppkg/dependencies/lib/$NEEDED_SHARED_LIBRARY_FILENAME"

                        if [ ! -f "$F" ] ; then
                            run cp -L "$NEEDED_SHARED_LIBRARY_FILEPATH" "$F"
                        fi

                        break
                    }
                done
            fi
        fi

        if [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then
            __check_DT_NEEDED "$NEEDED_SHARED_LIBRARY_FILEPATH"
        else
            F=".ppkg/dependencies/sys/$NEEDED_SHARED_LIBRARY_FILENAME"

            if [ ! -f "$F" ] ; then
                touch "$F"
            fi
        fi
    done
}

__check_mach_o_files() {
    find -type f -printf '%P\n' > files.txt

    while read -r FILEPATH
    do
        FILE_HEADER_ACTUAL=
        FILE_HEADER_ACTUAL="$("$PPKG_CORE_DIR/read-first-n-bytes" 16 "$FILEPATH")"

        unset LIBRARY
        unset EXECUTABLE

        # https://github.com/aidansteele/osx-abi-macho-file-format-reference
        case $FILE_HEADER_ACTUAL in
            CFFAEDFE0C0000010000000002000000)
                # arm64 executable
                EXECUTABLE=1
                ;;
            CFFAEDFE0C0000010000000006000000)
                # arm64 shared library
                LIBRARY=1
                ;;
            CFFAEDFE0C0000010000000008000000)
                # arm64 bundle library
                LIBRARY=1
                ;;
            CFFAEDFE070000010300000002000000)
                # x86_64 executable
                EXECUTABLE=1
                ;;
            CFFAEDFE070000010300000006000000)
                # x86_64 shared library
                LIBRARY=1
                ;;
            CFFAEDFE070000010300000008000000)
                # x86_64 bundle library
                LIBRARY=1
                ;;
            *)  #echo "$FILE_HEADER_ACTUAL:$FILEPATH"
                continue
        esac

        #######################################################################

        DYLIB_ID=$(otool -l "$FILEPATH" | grep LC_ID_DYLIB -A2 | grep name | sed 's|^[[:space:]]*||' | cut -d ' ' -f2)

        RUNPATHs=$(otool -l "$FILEPATH" | grep LC_RPATH    -A2 | grep path | sed 's|^[[:space:]]*||' | cut -d ' ' -f2)

        #######################################################################

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            cat <<EOF
FILEPATH = $FILEPATH
DYLIB_ID = $DYLIB_ID
RUNPATHs = $RUNPATHs
EOF
        fi

        #######################################################################

        case $DYLIB_ID in
            '') ;;
            @rpath/*)
                ;;
            @loader_path/*)
                ;;
            @executable_path/*)
                ;;
            @*) abort 1 "unexpected LC_ID_DYLIB($DYLIB_ID) in $FILEPATH"
                ;;
            *)  run install_name_tool -id "@rpath/${DYLIB_ID##*/}" "$FILEPATH"
        esac

        #######################################################################

        for RPATH in $RUNPATHs
        do
            case $RPATH in
                @loader_path)
                    ;;
                @loader_path/*)
                    ;;
                @executable_path)
                    ;;
                @executable_path/*)
                    ;;
                /usr/lib/*)
                    ;;
                /System/Library/Frameworks/*)
                    ;;
                /*) run install_name_tool -delete_rpath "$RPATH" "$FILEPATH"
            esac
        done

        #######################################################################

        if [ "$LIBRARY" = 1 ] ; then
            run install_name_tool -add_rpath '@loader_path' "$FILEPATH" || true
        fi

        #######################################################################

        __check_needed_dylibs "$FILEPATH" "$EXECUTABLE"
    done < files.txt

    rm files.txt
}

# __find_needed_shared_library <NEEDED_SHARED_LIBRARY_FILENAME>
  __find_needed_shared_library() {
    unset NEEDED_SHARED_LIBRARY_FILEPATH

    if [ -d lib ] ; then
        NEEDED_SHARED_LIBRARY_FILEPATH="lib/$1"

        [ -f "$NEEDED_SHARED_LIBRARY_FILEPATH" ] || {
            unset NEEDED_SHARED_LIBRARY_FILEPATH
            NEEDED_SHARED_LIBRARY_FILEPATH="$(find -L lib -type f -name "$1" -print -quit)"
        }
    fi

    if [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then
        return 0
    fi

    for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
    do
        NEEDED_SHARED_LIBRARY_ROOT_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME/lib"

        [ -d "$NEEDED_SHARED_LIBRARY_ROOT_DIR" ] || continue

        NEEDED_SHARED_LIBRARY_FILEPATH="$NEEDED_SHARED_LIBRARY_ROOT_DIR/$1"

        [ -f "$NEEDED_SHARED_LIBRARY_FILEPATH" ] && break

        NEEDED_SHARED_LIBRARY_FILEPATH="$(find -L "$NEEDED_SHARED_LIBRARY_ROOT_DIR" -type f -name "$1" -print -quit)"

        [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] && break
    done

    return 0
}

# __check_needed_dylibs <MACH-O-FILE-PATH> <IS-EXECUTABLE>
  __check_needed_dylibs() {
    X="$(printf '%s\n' "$1" | tr / _)"
    Y="$PACKAGE_WORKING_DIR/map/$X"

    if [ -f "$Y" ] ; then
        return 0
    else
        touch "$Y"
    fi

    NEEDEDs=$(otool -l "$1" | grep LC_LOAD_DYLIB -A2 | grep name | sed 's|^[[:space:]]*||' | cut -d ' ' -f2)

    if [ -z "$NEEDEDs" ] ; then
        abort 1 "no needed shared libraries set for $1"
    fi

    if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
        cat <<EOF
FILEPATH = $1
NEEDEDs  = $NEEDEDs
EOF
    fi

    for NEEDED in $NEEDEDs
    do
        case $NEEDED in
            /usr/lib/lib*.dylib)
                ;;
            /usr/lib/swift/lib*.dylib)
                ;;
            /System/Library/Frameworks/*)
                ;;
            /System/Library/PrivateFrameworks/*)
                ;;
            $PACKAGE_INSTALL_DIR/*)
                NEEDED_SHARED_LIBRARY_FILENAME="${NEEDED##*/}"

                run install_name_tool -change "$NEEDED" "@rpath/$NEEDED_SHARED_LIBRARY_FILENAME" "$1"

                NEEDED_SHARED_LIBRARY_DIR="${NEEDED%/*}"

                if [ "$2" = 1 ] ; then
                    RELATIVE_PATH="${NEEDED_SHARED_LIBRARY_DIR#$PACKAGE_INSTALL_DIR/}"
                    FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|$RELATIVE_PATH"
                fi
                ;;
            /*)
                NEEDED_SHARED_LIBRARY_FILENAME="${NEEDED##*/}"

                run install_name_tool -change "$NEEDED" "@rpath/$NEEDED_SHARED_LIBRARY_FILENAME" "$1"

                F=".ppkg/dependencies/lib/$NEEDED_SHARED_LIBRARY_FILENAME"

                if [ ! -f "$F" ] ; then
                    run cp -L "$NEEDED" "$F"
                fi

                if [ "$2" = 1 ] ; then
                    FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|1"
                fi
                ;;
            lib*.dylib)
                run install_name_tool -change "$NEEDED" "@rpath/$NEEDED" "$1"

                __find_needed_shared_library "$NEEDED"

                if [ -z "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then
                    abort 1 "$NEEDED was not found, which is needed by $1"
                fi

                case $NEEDED_SHARED_LIBRARY_FILEPATH in
                    /*)
                        F=".ppkg/dependencies/lib/$NEEDED"

                        if [ ! -f "$F" ] ; then
                            run cp -L "$NEEDED_SHARED_LIBRARY_FILEPATH" "$F"
                        fi

                        if [ "$2" = 1 ] ; then
                            FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|1"
                        fi
                        ;;
                    *)
                        if [ "$2" = 1 ] ; then
                            FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|${NEEDED_SHARED_LIBRARY_FILEPATH%/*}"
                        fi
                esac

                __check_needed_dylibs "$NEEDED_SHARED_LIBRARY_FILEPATH" 0
                ;;
            @rpath/libclang_rt*)
                ;;
            @rpath/*)
                NEEDED_SHARED_LIBRARY_FILENAME="${NEEDED#*/}"

                __find_needed_shared_library "$NEEDED_SHARED_LIBRARY_FILENAME"

                if [ -z "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then
                    abort 1 "$NEEDED was not found, which is needed by $1"
                fi

                case $NEEDED_SHARED_LIBRARY_FILEPATH in
                    /*)
                        F=".ppkg/dependencies/lib/$NEEDED_SHARED_LIBRARY_FILENAME"

                        if [ ! -f "$F" ] ; then
                            run cp -L "$NEEDED_SHARED_LIBRARY_FILEPATH" "$F"
                        fi

                        if [ "$2" = 1 ] ; then
                            FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|1"
                        fi
                        ;;
                    *)
                        if [ "$2" = 1 ] ; then
                            FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|${NEEDED_SHARED_LIBRARY_FILEPATH%/*}"
                        fi
                esac

                __check_needed_dylibs "$NEEDED_SHARED_LIBRARY_FILEPATH" 0
                ;;
            @loader_path/*)
                ;;
            @executable_path/*)
                ;;
            #*)  abort 1 "unexpected runtime dependency: $NEEDED , which is needed by $1"
        esac
    done
}

__tweak_pc_files() {
    unset pcfiles

    for item in lib share
    do
        pcfiles_LIVEDIR="$PACKAGE_INSTALL_DIR/$item/pkgconfig"

        if [ -d        "$pcfiles_LIVEDIR" ] ; then
            fs="$(find "$pcfiles_LIVEDIR" -type f -name '*.pc')"

            if [ -n "$fs" ] ; then
                pcfiles="$pcfiles $fs"
            fi
        fi
    done

    [ -z "$pcfiles" ] && return 0

    step "tweak .pc files"

    for pcfile in $pcfiles
    do
        gsed -i \
             -e "s|$PACKAGE_INSTALL_DIR|\${pcfiledir}/../..|g" \
             -e "s|-I$PPKG_HOME[^' ]*||g" \
             -e "s|-L$PPKG_HOME[^' ]*||g" \
             -e "s|-R[^' ]*||g" \
             -e "s|-F[^' ]*||g" \
             -e "s|-idirafter[^' ]*||g" \
             -e "s|-isysroot [^' ]*||g" \
             -e 's|-flto||g' \
             -e 's|-Wl,--strip-debug||g' \
             -e 's|-Wl,-search_paths_first||g' \
             -e 's|-Wl,-S||g' \
             -e "s|${PPKG_HOME}/.*/lib\(.*\)\.${SHARED_LIBRARY_SUFFIX#.}|-l\1|g" \
             -e "s|${PPKG_HOME}/.*/lib\(.*\)\.a|-l\1|g" \
             "$pcfile"

        if [ -n "$SYSROOT" ] ; then
            gsed -i -e "s|-L$SYSROOT[^' ]*||g" -e "s|--sysroot=$SYSROOT||" "$pcfile"
        fi

        if grep -q '^Libs.private:' "$pcfile" ; then
            if grep -q '^Libs:' "$pcfile" ; then
                LIBS_PRIVATE=$(gsed -n '/^Libs.private:/p' "$pcfile" | cut -c14-)
                gsed -i "/Libs:/s|\$|$LIBS_PRIVATE|" "$pcfile"
                gsed -i '/Libs.private/d' "$pcfile"
            else
                gsed -i 's|Libs.private:|Libs:|' "$pcfile"
            fi
        fi

        if grep -q '^Requires.private:' "$pcfile" ; then
            if grep -q '^Requires:' "$pcfile" ; then
                REQUIRES_PRIVATE=$(gsed -n '/Requires.private:/p' "$pcfile" | cut -c18-)
                gsed -i "/Requires:/s|\$|$REQUIRES_PRIVATE|" "$pcfile"
                gsed -i '/Requires.private:/d' "$pcfile"
            else
                gsed -i 's|Requires.private:|Requires:|' "$pcfile"
            fi
        fi
    done
}

# install_incs [:sub-dir] <FILE>...
install_incs() {
    unset X

    case $1 in
        :*) X="${1#:}"; shift
    esac

    while [ -n "$1" ]
    do
        install -v -d          "$PACKAGE_INSTALL_DIR/include/$X/"
        install -v -m 644 "$1" "$PACKAGE_INSTALL_DIR/include/$X/"
        shift
    done
}

install_libs() {
    install -v -d "$PACKAGE_INSTALL_DIR/lib"
    for item in "$@"
    do
        case $item in
            *.a) install -v -m 644 "$item" "$PACKAGE_INSTALL_DIR/lib" ;;
            *)   install -v -m 755 "$item" "$PACKAGE_INSTALL_DIR/lib" ;;
        esac
    done
}

writepc() {
    install -v -d "$PACKAGE_INSTALL_DIR/lib/pkgconfig" &&
    cat >         "$PACKAGE_INSTALL_DIR/lib/pkgconfig/$1.pc"
}

install_pcfs() {
    install -v -d          "$PACKAGE_INSTALL_DIR/lib/pkgconfig" &&
    install -v -m 644 "$@" "$PACKAGE_INSTALL_DIR/lib/pkgconfig"
}

install_bins() {
    install -v -d          "$PACKAGE_INSTALL_DIR/bin" &&
    install -v -m 755 "$@" "$PACKAGE_INSTALL_DIR/bin"
}

install_etcs() {
    install -v -d          "$PACKAGE_INSTALL_DIR/etc" &&
    install -v -m 644 "$@" "$PACKAGE_INSTALL_DIR/etc"
}

install_mans() {
    for item in "$@"
    do
        unset NUMBER
        NUMBER=$(echo "$item" | cut -c ${#item}-${#item})
        case $NUMBER in
            [1-8]);;
            *)    abort 1 "$item: not a manpage."
        esac
        install -v -d             "$PACKAGE_INSTALL_DIR/share/man/man$NUMBER" &&
        install -v -m 644 "$item" "$PACKAGE_INSTALL_DIR/share/man/man$NUMBER"
    done
}

# install_completion <fish|bash|zsh> <COMMAND> <FILE-PATH>
  install_completion() {
    case $1 in
        bash)
            install -v -d          "$PACKAGE_INSTALL_DIR/share/bash/completions" &&
            install -v -m 644 "$3" "$PACKAGE_INSTALL_DIR/share/bash/completions/$2"
            ;;
        fish)
            install -v -d          "$PACKAGE_INSTALL_DIR/share/fish/vendor_completions.d" &&
            install -v -m 644 "$3" "$PACKAGE_INSTALL_DIR/share/fish/vendor_completions.d/$2.fish"
            ;;
        zsh)
            install -v -d          "$PACKAGE_INSTALL_DIR/share/zsh/site-functions" &&
            install -v -m 644 "$3" "$PACKAGE_INSTALL_DIR/share/zsh/site-functions/_$2"
            ;;
        *)  abort 1 "install_completion unsupported shell: $1"
    esac
}

# __symlink_installed_files_of_the_given_package <PACKAGE-NAME>
  __symlink_installed_files_of_the_given_package() {
    # while read -r item
    # do
    #     X=$(printf '%s\n' "$item" | cut -d '|' -f1)
    #     Y=$(printf '%s\n' "$item" | cut -d '|' -f3)

    #     case $X in
    #         d)  ;;
    #         D)  ;;
    #         *)  case $Y in
    #                 share/info/dir) ;;
    #                 *)  if [ -L "$PPKG_PACKAGE_SYMLINKED_ROOT/$Y" ] || [ -e "$PPKG_PACKAGE_SYMLINKED_ROOT/$Y" ] ; then
    #                         abort 1 "$PPKG_PACKAGE_SYMLINKED_ROOT/$Y already exists."
    #                     # else
    #                     #     echo "$PPKG_PACKAGE_SYMLINKED_ROOT/$Y"
    #                     fi
    #             esac
    #     esac
    # done < "$PACKAGE_MANIFEST_FILEPATH"

    # ############################################################################

    if [ !      -d "$PPKG_PACKAGE_SYMLINKED_ROOT/.registry" ] ; then
        install -d "$PPKG_PACKAGE_SYMLINKED_ROOT/.registry"
    fi

    exec 7> "$PPKG_PACKAGE_SYMLINKED_ROOT/.registry/$1"

    while read -r item
    do
        X=$(printf '%s\n' "$item" | cut -d '|' -f1)
        Y=$(printf '%s\n' "$item" | cut -d '|' -f3)

        case $X in
            d|D)
                if [ !      -d "$PPKG_PACKAGE_SYMLINKED_ROOT/$Y" ] ; then
                    install -d "$PPKG_PACKAGE_SYMLINKED_ROOT/$Y"
                fi
                ;;
            *)  case $Y in
                    share/info/dir) ;;
                    *)  run ln -sfr "\"$PPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$1/$Y\"" "\"$PPKG_PACKAGE_SYMLINKED_ROOT/$Y\""
                        printf '%s\n' "$Y" >&7
                esac
        esac
    done < "$PACKAGE_MANIFEST_FILEPATH"

    exec 7>&-
}

# }}}
##############################################################################
# {{{ operation of receipt

# __load_receipt_of_the_given_package <PACKAGE-NAME|PACKAGE-SPEC>
  __load_receipt_of_the_given_package() {
    PACKAGE_SPEC=
    PACKAGE_SPEC="$(inspect_package_spec "$1")"

    is_package_installed "$PACKAGE_SPEC" || return $?

    PACKAGE_INSTALLED_DIR="$(readlink -f "$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC")"

    PACKAGE_RECEIPT_FILEPATH="$PACKAGE_INSTALLED_DIR/.ppkg/RECEIPT.yml"

    unset RECEIPT_PACKAGE_PKGNAME
    unset RECEIPT_PACKAGE_PKGTYPE

    unset RECEIPT_PACKAGE_PROFILE

    unset RECEIPT_PACKAGE_SUMMARY
    unset RECEIPT_PACKAGE_VERSION
    unset RECEIPT_PACKAGE_LICENSE

    unset RECEIPT_PACKAGE_WEB_URL

    unset RECEIPT_PACKAGE_GIT_URL
    unset RECEIPT_PACKAGE_GIT_SHA
    unset RECEIPT_PACKAGE_GIT_REF
    unset RECEIPT_PACKAGE_GIT_NTH

    unset RECEIPT_PACKAGE_SRC_URL
    unset RECEIPT_PACKAGE_SRC_URI
    unset RECEIPT_PACKAGE_SRC_SHA

    unset RECEIPT_PACKAGE_FIX_URL
    unset RECEIPT_PACKAGE_FIX_URI
    unset RECEIPT_PACKAGE_FIX_SHA
    unset RECEIPT_PACKAGE_FIX_OPT

    unset RECEIPT_PACKAGE_RES_URL
    unset RECEIPT_PACKAGE_RES_URI
    unset RECEIPT_PACKAGE_RES_SHA

    unset RECEIPT_PACKAGE_PATCHES
    unset RECEIPT_PACKAGE_RESLIST

    unset RECEIPT_PACKAGE_DEP_PKG
    unset RECEIPT_PACKAGE_DEP_RES
    unset RECEIPT_PACKAGE_DEP_LIB
    unset RECEIPT_PACKAGE_DEP_UPP
    unset RECEIPT_PACKAGE_DEP_PYM
    unset RECEIPT_PACKAGE_DEP_PLM

    unset RECEIPT_PACKAGE_BSYSTEM
    unset RECEIPT_PACKAGE_BSCRIPT

    unset RECEIPT_PACKAGE_DOFETCH
    unset RECEIPT_PACKAGE_LTOABLE
    unset RECEIPT_PACKAGE_MOVABLE

    unset RECEIPT_PACKAGE_DO12345
    unset RECEIPT_PACKAGE_DOPATCH
    unset RECEIPT_PACKAGE_PREPARE
    unset RECEIPT_PACKAGE_DOBUILD
    unset RECEIPT_PACKAGE_DOTWEAK

    unset RECEIPT_PACKAGE_CAVEATS

    unset RECEIPT_PACKAGE_BUILTBY
    unset RECEIPT_PACKAGE_BUILTAT

    unset RECEIPT_PACKAGE_BUILTFOR
    unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM
    unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME
    unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM_VERS
    unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH

    unset RECEIPT_PACKAGE_SUPPORT_BUILD_IN_PARALLEL

    unset RECEIPT_PACKAGE_DEVELOPER

    #########################################################################################

    RECEIPT_PACKAGE_PKGNAME="$(yq '.pkgname | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_PKGTYPE="$(yq '.pkgtype | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_PROFILE="$(yq '.profile | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_SUMMARY="$(yq '.summary | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_LICENSE="$(yq '.license | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_VERSION="$(yq '.version | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_WEB_URL="$(yq '.web-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_GIT_URL="$(yq '.git-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_GIT_SHA="$(yq '.git-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_GIT_REF="$(yq '.git-ref | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_GIT_NTH="$(yq '.git-nth | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_SRC_URL="$(yq '.src-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_SRC_URI="$(yq '.src-uri | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_SRC_SHA="$(yq '.src-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_FIX_URL="$(yq '.fix-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_FIX_URI="$(yq '.fix-uri | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_FIX_SHA="$(yq '.fix-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_FIX_OPT="$(yq '.fix-opt | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_RES_URL="$(yq '.res-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_RES_URI="$(yq '.res-uri | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_RES_SHA="$(yq '.res-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_RESLIST="$(yq '.reslist | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_PATCHES="$(yq '.patches | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_DEP_PKG="$(yq '.dep-pkg | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DEP_RES="$(yq '.dep-res | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DEP_LIB="$(yq '.dep-lib | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DEP_UPP="$(yq '.dep-upp | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DEP_PYM="$(yq '.dep-pym | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DEP_PLM="$(yq '.dep-plm | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_BSYSTEM="$(yq '.bsystem | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_BSCRIPT="$(yq '.bscript | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_BINBSTD="$(yq '.binbstd | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_CCFLAGS="$(yq '.ccflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_XXFLAGS="$(yq '.xxflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_PPFLAGS="$(yq '.ppflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_LDFLAGS="$(yq '.ldflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_DOFETCH="$(yq '.dofetch | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DO12345="$(yq '.do12345 | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DOPATCH="$(yq '.dopatch | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_PREPARE="$(yq '.prepare | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DOBUILD="$(yq '.install | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DOTWEAK="$(yq '.dotweak | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_LTOABLE="$(yq '.ltoable | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_MOVABLE="$(yq '.movable | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_BINDENV="$(yq '.bindenv | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_CAVEATS="$(yq '.caveats | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_BUILTBY="$(yq '.builtby | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_BUILTAT="$(yq '.builtat | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_BUILTFOR="$(yq '.builtfor | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_SUPPORT_BUILD_IN_PARALLEL="$(yq '.parallel | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_DEVELOPER="$(yq '.developer | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    #########################################################################################

    [ -z "$RECEIPT_PACKAGE_PKGNAME" ] && abort 1 "receipt scheme error. pkgname mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_PKGTYPE" ] && abort 1 "receipt scheme error. pkgtype mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_VERSION" ] && abort 1 "receipt scheme error. version mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_SUMMARY" ] && abort 1 "receipt scheme error. summary mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_WEB_URL" ] && abort 1 "receipt scheme error. web-url mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_BUILTBY" ] && abort 1 "receipt scheme error. builtby mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_BUILTAT" ] && abort 1 "receipt scheme error. builtat mapping was not found in $PACKAGE_RECEIPT_FILEPATH."

    [ "${#RECEIPT_PACKAGE_BUILTAT}" -eq 10 ] || abort 1 "receipt scheme error. builtat mapping's value length should be 10."

    if [ "${PACKAGE_SPEC#*/}" != "$RECEIPT_PACKAGE_PKGNAME" ] ; then
        error "$PACKAGE_RECEIPT_FILEPATH is broken. value of RECEIPT_PACKAGE_PKGNAME does not identical with your request: ${PACKAGE_SPEC#*/}"
        return 1
    fi

    if [ "${PACKAGE_SPEC%/*}" != "$RECEIPT_PACKAGE_BUILTFOR" ] ; then
        error "$PACKAGE_RECEIPT_FILEPATH is broken. value of RECEIPT_PACKAGE_BUILTFOR does not identical with your request: ${PACKAGE_SPEC%/*}"
        return 1
    fi

    #########################################################################################

    RECEIPT_PACKAGE_BUILTFOR_PLATFORM="$RECEIPT_PACKAGE_BUILTFOR"

    RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME="$(printf '%s\n' "$RECEIPT_PACKAGE_BUILTFOR" | cut -d- -f1)"
    RECEIPT_PACKAGE_BUILTFOR_PLATFORM_VERS="$(printf '%s\n' "$RECEIPT_PACKAGE_BUILTFOR" | cut -d- -f2)"
    RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH="$(printf '%s\n' "$RECEIPT_PACKAGE_BUILTFOR" | cut -d- -f3)"
}

# }}}
##############################################################################
# {{{ ppkg install

__install_the_given_packages() {
    __inspect_install_arguments "$@"
    __initialize_environment_variables

    [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] && abort 1 "$PPKG_ARG0 install <PACKAGE-SPEC|PACKAGE-NAME>..., <|PACKAGE-SPEC|PACKAGE-NAME> is unspecified."

    #########################################################################################

    SESSION_DIR="$PPKG_HOME/run/$$"

    rm -rf     "$SESSION_DIR"
    install -d "$SESSION_DIR"

    #########################################################################################

    # 1. check if has circle
    # 2. backup formulas
    # 3. cache variables

    for PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        TARGET_PLATFORM_SPEC="${PACKAGE_SPEC%/*}"
        TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
        TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

        PACKAGE_NAME_STACK="${PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            if [ -f "$SESSION_DIR/$PACKAGE_NAME.yml" ] ; then
                continue
            fi

            __load_formula_of_the_given_package "$PACKAGE_NAME"

            cp "$PACKAGE_FORMULA_FILEPATH" "$SESSION_DIR/$PACKAGE_NAME.yml"

            eval "PACKAGE_DEP_PKG_${PACKAGE_NAME_UPPERCASE_UNDERSCORE}='$PACKAGE_DEP_PKG'"

            for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
            do
                if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then
                    abort 1 "package '$PACKAGE_NAME' depends itself."
                fi

                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$DEPENDENT_PACKAGE_NAME"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$DEPENDENT_PACKAGE_NAME"
                fi
            done
        done
    done

    #########################################################################################

    for PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        TARGET_PLATFORM_SPEC="${PACKAGE_SPEC%/*}"
        TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
        TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

        ##################################################################

        REQUESTED_PACKAGE_NAME_LIST=

        PACKAGE_NAME_STACK="${PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            ##################################################################

            REQUESTED_PACKAGE_NAME_LIST2="$PACKAGE_NAME"

            for item in $REQUESTED_PACKAGE_NAME_LIST
            do
                [ "$item" = "$PACKAGE_NAME" ] && continue
                REQUESTED_PACKAGE_NAME_LIST2="$REQUESTED_PACKAGE_NAME_LIST2 $item"
            done

            REQUESTED_PACKAGE_NAME_LIST="$REQUESTED_PACKAGE_NAME_LIST2"

            ##################################################################

            PACKAGE_NAME_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')"

            for item in $(eval echo \$PACKAGE_DEP_PKG_"${PACKAGE_NAME_UPPERCASE_UNDERSCORE}")
            do
                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$item"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item"
                fi
            done
        done

        ##################################################################

        for PACKAGE_NAME in $REQUESTED_PACKAGE_NAME_LIST
        do
            PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME"

            if is_package_installed "$PACKAGE_SPEC" ; then
                if [ "$UPGRAGE" = 1 ] ; then
                    if is_package__outdated "$PACKAGE_SPEC" ; then
                        (__install_the_given_package "$PACKAGE_SPEC")
                    else
                        if [ "$LOG_LEVEL" -ne 0 ] ; then
                            printf "$COLOR_GREEN%-10s$COLOR_OFF already have been installed and is up-to-date.\n" "$PACKAGE_SPEC"
                        fi
                    fi
                else
                    if [ "$LOG_LEVEL" -ne 0 ] ; then
                        printf "$COLOR_GREEN%-10s$COLOR_OFF already have been installed.\n" "$PACKAGE_SPEC"
                    fi
                fi
            else
                (__install_the_given_package "$PACKAGE_SPEC")
            fi
        done
    done

    #########################################################################################

    if [ "$REQUEST_TO_KEEP_SESSION_DIR" != 1 ] ; then
        rm -rf "$SESSION_DIR"
    fi
}

# }}}
##############################################################################
# {{{ ppkg reinstall

__reinstall_the_given_packages() {
    __inspect_install_arguments "$@"
    __initialize_environment_variables

    [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] && abort 1 "neither package-name nor package-spec is specified."

    #########################################################################################

    SESSION_DIR="$PPKG_HOME/run/$$"

    rm -rf     "$SESSION_DIR"
    install -d "$SESSION_DIR"

    #########################################################################################

    # 1. check if has circle
    # 2. backup formulas
    # 3. cache variables

    for PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        TARGET_PLATFORM_SPEC="${PACKAGE_SPEC%/*}"
        TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
        TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

        PACKAGE_NAME_STACK="${PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            if [ -f "$SESSION_DIR/$PACKAGE_NAME.yml" ] ; then
                continue
            fi

            __load_formula_of_the_given_package "$PACKAGE_NAME"

            cp "$PACKAGE_FORMULA_FILEPATH" "$SESSION_DIR/$PACKAGE_NAME.yml"

            eval "PACKAGE_DEP_PKG_${PACKAGE_NAME_UPPERCASE_UNDERSCORE}='$PACKAGE_DEP_PKG'"

            for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
            do
                if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then
                    abort 1 "package '$PACKAGE_NAME' depends itself."
                fi

                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$DEPENDENT_PACKAGE_NAME"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$DEPENDENT_PACKAGE_NAME"
                fi
            done
        done
    done

    #########################################################################################

    for PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        TARGET_PLATFORM_SPEC="${PACKAGE_SPEC%/*}"
        TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
        TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

        ##################################################################

        REQUESTED_PACKAGE_NAME_LIST=

        PACKAGE_NAME_STACK="${PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            ##################################################################

            REQUESTED_PACKAGE_NAME_LIST2="$PACKAGE_NAME"

            for item in $REQUESTED_PACKAGE_NAME_LIST
            do
                [ "$item" = "$PACKAGE_NAME" ] && continue
                REQUESTED_PACKAGE_NAME_LIST2="$REQUESTED_PACKAGE_NAME_LIST2 $item"
            done

            REQUESTED_PACKAGE_NAME_LIST="$REQUESTED_PACKAGE_NAME_LIST2"

            ##################################################################

            PACKAGE_NAME_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')"

            for item in $(eval echo \$PACKAGE_DEP_PKG_"${PACKAGE_NAME_UPPERCASE_UNDERSCORE}")
            do
                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$item"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item"
                fi
            done
        done

        ##################################################################

        for PACKAGE_NAME in $REQUESTED_PACKAGE_NAME_LIST
        do
            PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME"

            PACKAGE_INSTALLED_LINK_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
            PACKAGE_INSTALLED_REAL_DIR="$(readlink -f "$PACKAGE_INSTALLED_LINK_DIR")"

            (__install_the_given_package "$PACKAGE_SPEC")

            rm -rf "$PACKAGE_INSTALLED_REAL_DIR"
        done
    done

    #########################################################################################

    if [ "$REQUEST_TO_KEEP_SESSION_DIR" != 1 ] ; then
        rm -rf "$SESSION_DIR"
    fi
}

# }}}
##############################################################################
# {{{ ppkg upgrade

__upgrade_packages() {
    __inspect_install_arguments "$@"
    __initialize_environment_variables

    if [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] ; then
        SPECIFIED_PACKAGE_SPEC_LIST=$(__list__outdated_packages)
    fi

    if [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] ; then
        return 0
    fi

    #########################################################################################

    SESSION_DIR="$PPKG_HOME/run/$$"

    rm -rf     "$SESSION_DIR"
    install -d "$SESSION_DIR"

    #########################################################################################

    # 1. check if has circle
    # 2. backup formulas
    # 3. cache variables

    for PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        TARGET_PLATFORM_SPEC="${PACKAGE_SPEC%/*}"
        TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
        TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

        PACKAGE_NAME_STACK="${PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            if [ -f "$SESSION_DIR/$PACKAGE_NAME.yml" ] ; then
                continue
            fi

            __load_formula_of_the_given_package "$PACKAGE_NAME"

            cp "$PACKAGE_FORMULA_FILEPATH" "$SESSION_DIR/$PACKAGE_NAME.yml"

            eval "PACKAGE_DEP_PKG_${PACKAGE_NAME_UPPERCASE_UNDERSCORE}='$PACKAGE_DEP_PKG'"

            for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
            do
                if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then
                    abort 1 "package '$PACKAGE_NAME' depends itself."
                fi

                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$DEPENDENT_PACKAGE_NAME"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$DEPENDENT_PACKAGE_NAME"
                fi
            done
        done
    done

    #########################################################################################

    for PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        TARGET_PLATFORM_SPEC="${PACKAGE_SPEC%/*}"
        TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
        TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

        ##################################################################

        REQUESTED_PACKAGE_NAME_LIST=

        PACKAGE_NAME_STACK="${PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            ##################################################################

            REQUESTED_PACKAGE_NAME_LIST2="$PACKAGE_NAME"

            for item in $REQUESTED_PACKAGE_NAME_LIST
            do
                [ "$item" = "$PACKAGE_NAME" ] && continue
                REQUESTED_PACKAGE_NAME_LIST2="$REQUESTED_PACKAGE_NAME_LIST2 $item"
            done

            REQUESTED_PACKAGE_NAME_LIST="$REQUESTED_PACKAGE_NAME_LIST2"

            ##################################################################

            PACKAGE_NAME_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')"

            for item in $(eval echo \$PACKAGE_DEP_PKG_"${PACKAGE_NAME_UPPERCASE_UNDERSCORE}")
            do
                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$item"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item"
                fi
            done
        done

        ##################################################################

        for PACKAGE_NAME in $REQUESTED_PACKAGE_NAME_LIST
        do
            PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME"

            is_package__outdated "$PACKAGE_SPEC" || {
                note 1 "$PACKAGE_SPEC is not outdated."
                continue
            }

            PACKAGE_INSTALLED_LINK_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
            PACKAGE_INSTALLED_REAL_DIR="$(readlink -f "$PACKAGE_INSTALLED_LINK_DIR")"

            (__install_the_given_package "$PACKAGE_SPEC")

            rm -rf "$PACKAGE_INSTALLED_REAL_DIR"
        done
    done

    #########################################################################################

    if [ "$REQUEST_TO_KEEP_SESSION_DIR" != 1 ] ; then
        rm -rf "$SESSION_DIR"
    fi
}

# }}}
##############################################################################
# {{{ ppkg uninstall

__uninstall_the_given_packages() {
    [ -z "$1" ] && abort 1 "neither package-name nor package-spec is specified."

    unset PACKAGE_SPECS

    for item in "$@"
    do
        PACKAGE_SPECS="$PACKAGE_SPECS $(inspect_package_spec "$item")"
    done

    for PACKAGE_SPEC in $PACKAGE_SPECS
    do
        PACKAGE_INSTALLED_LINK_DIR="$PPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"

        [ -e "$PACKAGE_INSTALLED_LINK_DIR" ] || abort 10 "package '$PACKAGE_SPEC' is not installed."
        [ -L "$PACKAGE_INSTALLED_LINK_DIR" ] || abort 11 "$PACKAGE_INSTALLED_LINK_DIR was expected a symlink, but it was not."
        [ -d "$PACKAGE_INSTALLED_LINK_DIR" ] || abort 12 "$PACKAGE_INSTALLED_LINK_DIR was expected a symlink refer to a directory, but it was not."

        PACKAGE_INSTALLED_REAL_DIR="$(readlink -f "$PACKAGE_INSTALLED_LINK_DIR")"

        [ -d "$PACKAGE_INSTALLED_REAL_DIR" ] || abort 13 "directory $PACKAGE_INSTALLED_REAL_DIR was expected exists, but it was not."

        PACKAGE_MANIFEST_FILEPATH="$PACKAGE_INSTALLED_REAL_DIR/.ppkg/MANIFEST.txt"

        [ -f "$PACKAGE_MANIFEST_FILEPATH" ] || abort 13 "$PACKAGE_MANIFEST_FILEPATH file was expected exist, but it was not."

        PACKAGE_RECEIPT_FILEPATH="$PACKAGE_INSTALLED_REAL_DIR/.ppkg/RECEIPT.yml"

        [ -f "$PACKAGE_RECEIPT_FILEPATH" ] || abort 14 "$PACKAGE_RECEIPT_FILEPATH file was expected exist, but it was not."

        run rm -ff "$PACKAGE_INSTALLED_LINK_DIR"
        run rm -rf "$PACKAGE_INSTALLED_REAL_DIR"
    done
}

# }}}
##############################################################################
# {{{ ppkg upgrade-self

# __upgrade_self <URL>
  __upgrade_self() {
    [ -z "$1" ] && abort 1 "__upgrade_self <URL> , <URL> should be non-empty."

    unset CURRENT_SCRIPT_REALPATH

    # if file exists and is a symbolic link
    if [ -L "$PPKG_PATH" ] ; then
        # https://unix.stackexchange.com/questions/136494/whats-the-difference-between-realpath-and-readlink-f#:~:text=GNU%20coreutils%20introduced%20a%20realpath,in%20common%20with%20GNU%20readlink%20.
        if command -v realpath > /dev/null ; then
            CURRENT_SCRIPT_REALPATH=$(realpath "$PPKG_PATH")
        elif command -v readlink > /dev/null && readlink -f xx > /dev/null 2>&1 ; then
            CURRENT_SCRIPT_REALPATH=$(readlink -f "$PPKG_PATH")
        else
            CURRENT_SCRIPT_REALPATH=$(realpath "$PPKG_PATH")
        fi
    else
        CURRENT_SCRIPT_REALPATH="$PPKG_PATH"
    fi

    SESSION_DIR="$PPKG_HOME/run/$$"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    wfetch "$1" -o self

    run chmod 755 self

    if [ -w "$CURRENT_SCRIPT_REALPATH" ] ; then
        run      mv self "$CURRENT_SCRIPT_REALPATH"
    else
        run sudo mv self "$CURRENT_SCRIPT_REALPATH"
    fi

    run rm -rf "$SESSION_DIR"
}

# }}}
##############################################################################
# {{{ ppkg integrate zsh

# __integrate_zsh_completions <URL> [--output-dir=<DIR>]
  __integrate_zsh_completions() {
    [ -z "$1" ] && abort 1 "__integrate_zsh_completions <URL> [--output-dir=<DIR>] , <URL> should be non-empty."

    ZSH_COMPLETIONS_SCRIPT_URL="$1"

    shift

    unset OUTPUT_DIR

    for arg in "$@"
    do
        case $arg in
            --output-dir=*)
                OUTPUT_DIR="${1#*=}"

                case $OUTPUT_DIR in
                    '')  abort 1 "__integrate_zsh_completions <URL> [--output-dir=<DIR>] , <DIR> should be a non-empty string." ;;
                    /*)  ;;
                    ~)   OUTPUT_DIR="$HOME" ;;
                    ~/)  OUTPUT_DIR="$HOME" ;;
                    ~/.) OUTPUT_DIR="$HOME" ;;
                    ~/*) OUTPUT_DIR="$HOME/${OUTPUT_DIR#~/}" ;;
                    *)   OUTPUT_DIR="$PWD/$OUTPUT_DIR"
                esac

                ;;
            *)  abort 1 "__integrate_zsh_completions <URL> [--output-dir=<DIR>] , unrecognized argument: $arg"
        esac
    done

    ZSH_COMPLETIONS_SCRIPT_FILENAME="_$(basename "$PPKG_ARG0")"

    if [ -n "$OUTPUT_DIR" ] ; then
        ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH="$OUTPUT_DIR/$ZSH_COMPLETIONS_SCRIPT_FILENAME"
    elif [ "$(uname)" = Linux ] && command -v termux-info > /dev/null && [ "$HOME" = '/data/data/com.termux/files/home' ] ; then
        ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH="/data/data/com.termux/files/usr/share/zsh/site-functions/$ZSH_COMPLETIONS_SCRIPT_FILENAME"
    else
        ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH="/usr/local/share/zsh/site-functions/$ZSH_COMPLETIONS_SCRIPT_FILENAME"
    fi

    # if file exists and is a symbolic link
    if [ -L "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" ] ; then
        # https://unix.stackexchange.com/questions/136494/whats-the-difference-between-realpath-and-readlink-f#:~:text=GNU%20coreutils%20introduced%20a%20realpath,in%20common%20with%20GNU%20readlink%20.
        if command -v realpath > /dev/null ; then
            ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH=$(realpath "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH")
        elif command -v readlink > /dev/null && readlink -f xx > /dev/null 2>&1 ; then
            ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH=$(readlink -f "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH")
        else
            ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH=$(realpath "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH")
        fi
    fi

    SESSION_DIR="$PPKG_HOME/run/$$"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    wfetch "$ZSH_COMPLETIONS_SCRIPT_URL" -o _ppkg

    run chmod 644 _ppkg

    if [ -f "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" ] ; then
        if [ -w "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" ] ; then
            run      mv _ppkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH"
        else
            run sudo mv _ppkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH"
        fi
    else
        ZSH_COMPLETIONS_SCRIPT_OUT_DIR="$(dirname "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH")"

        if [ ! -d "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" ] ; then
            run install -d "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" || run sudo install -d "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR"
        fi

        if [ -w "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" ] ; then
            run      mv _ppkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH"
        else
            run sudo mv _ppkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH"
        fi
    fi

    run rm -rf "$SESSION_DIR"

    printf '\n'
    note "${COLOR_YELLOW}you may need to run command${COLOR_RED} ${COLOR_GREEN}autoload -U compinit && compinit${COLOR_OFF} ${COLOR_YELLOW}in zsh to make it work.${COLOR_OFF}"
}

# }}}
##############################################################################
# {{{ ppkg gen-url-transform-sample

__gen_url_transform_sample() {
    SESSION_DIR="$PPKG_HOME/run/$$"

    rm -rf     "$SESSION_DIR"
    install -d "$SESSION_DIR"
    cd         "$SESSION_DIR"

    cat > url-transform.sample <<EOF
#!/bin/sh

# https://gitmirror.com/
case \$1 in
    *githubusercontent.com/*)
        printf '%s\n' "\$1" | sed 's|githubusercontent|gitmirror|'
        ;;
    https://github.com/*)
        printf 'https://hub.gitmirror.com/%s\n' "\$1"
        ;;
    '') printf '%s\n' "\$0 <URL>, <URL> is unspecified." >&2 ; exit 1 ;;
    *)  printf '%s\n' "\$1"
esac
EOF

    chmod +x url-transform.sample

    install -d "$PPKG_HOME"

    mv url-transform.sample "$PPKG_HOME/"

    rm -rf "$SESSION_DIR"

    success "url-transform sample has been written into $PPKG_HOME/url-transform.sample"
    note "You can rename url-transform.sample to url-transform then edit it to meet your needs. To apply this, you should run 'export PPKG_URL_TRANSFORM=$PPKG_HOME/url-transform' in your terminal."
}

# }}}
##############################################################################
# {{{ ppkg cleanup

__cleanup() {
    success "Done."
}

# }}}
##############################################################################
# {{{ ppkg setup

__setup_syspm_ubuntu() {
    SYSPM=apt

    run $sudo apt -y update
    run $sudo apt -y install bash coreutils findutils gawk sed grep tree jq libarchive-tools git curl g++ linux-headers-generic
}

__setup_syspm_fedora() {
    SYSPM=dnf

    run $sudo dnf -y update
    run $sudo dnf -y install bash coreutils findutils gawk sed grep tree jq libarchive-tools git curl g++
}

__setup_syspm_alpine() {
    SYSPM=apk

    run $sudo apk update
    run $sudo apk add bash coreutils findutils gawk sed grep tree jq yq libarchive-tools git curl g++ libc-dev linux-headers

    run ln -s /usr/bin/make bin/gmake
    run ln -s     /bin/sed  bin/gsed

    printf 'export ACLOCAL_PATH=/usr/share/aclocal\n' > init.sh
}

__setup_syspm_macos() {
    SYSPM=brew

    BREW="$(command -v brew || true)"

    if [ -z "$BREW" ] ; then
        wfetch 'https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh' -o homebrew-install.sh --no-buffer
        run "yes | bash homebrew-install.sh"

        BREW=$(command -v brew || true)
    else
        run "$BREW" update
    fi

    unset BREW_PACKAGE_EXEFIND_PATH

    for item in coreutils findutils gawk gsed grep libarchive git curl tree jq yq d2
    do
        run "$BREW" install "$item"

        BREW_PACKAGE_INSTALLED_DIR=
        BREW_PACKAGE_INSTALLED_DIR="$(brew --prefix "$item")"

        if [ -d "$BREW_PACKAGE_INSTALLED_DIR/bin" ] ; then
            BREW_PACKAGE_EXEFIND_PATH="$BREW_PACKAGE_EXEFIND_PATH:$BREW_PACKAGE_INSTALLED_DIR/bin"
        fi

        if [ -d "$BREW_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            BREW_PACKAGE_EXEFIND_PATH="$BREW_PACKAGE_EXEFIND_PATH:$BREW_PACKAGE_INSTALLED_DIR/sbin"
        fi

        if [ -d "$BREW_PACKAGE_INSTALLED_DIR/libexec/gnubin" ] ; then
            BREW_PACKAGE_EXEFIND_PATH="$BREW_PACKAGE_EXEFIND_PATH:$BREW_PACKAGE_INSTALLED_DIR/libexec/gnubin"
        fi
    done

    BREW_PACKAGE_EXEFIND_PATH="${BREW_PACKAGE_EXEFIND_PATH#':'}"

    if [ "$NATIVE_PLATFORM_ARCH" = x86_64 ] ; then
        BREW_BIN_DIR='/usr/local/bin'
    else
        BREW_BIN_DIR='/opt/homebrew/bin'
    fi

    run ln -s $BREW_BIN_DIR/gln      bin/ln
    run ln -s $BREW_BIN_DIR/gsed     bin/sed
    run ln -s $BREW_BIN_DIR/gawk     bin/awk
    run ln -s $BREW_BIN_DIR/ggrep    bin/grep
    run ln -s $BREW_BIN_DIR/gfind    bin/find
    run ln -s $BREW_BIN_DIR/gbase64  bin/base64
    run ln -s $BREW_BIN_DIR/gunlink  bin/unlink
    run ln -s $BREW_BIN_DIR/ginstall bin/install
    run ln -s $BREW_BIN_DIR/gsha256sum bin/sha256sum

    cat > init.sh <<EOF
export ACLOCAL_PATH=/usr/local/share/aclocal
export PATH="$BREW_PACKAGE_EXEFIND_PATH:\$PATH"
EOF
}

__setup_syspm_dragonflybsd() {
    SYSPM=pkg

    #run $sudo pkg update || true
    run $sudo pkg install -y bash coreutils findutils gawk gsed gnugrep tree jq git curl libnghttp2 gcc

    run ln -s /usr/local/go122/bin/go   bin/go

    run ln -s /usr/local/bin/gln        bin/ln
    run ln -s /usr/local/bin/gm4        bin/m4
    run ln -s /usr/local/bin/gsed       bin/sed
    run ln -s /usr/local/bin/gawk       bin/awk
    run ln -s /usr/local/bin/ggrep      bin/grep
    run ln -s /usr/local/bin/gfind      bin/find
    run ln -s /usr/local/bin/gmake      bin/make
    run ln -s /usr/local/bin/gnustat    bin/stat
    run ln -s /usr/local/bin/gdate      bin/date
    run ln -s /usr/local/bin/gnproc     bin/nproc
    run ln -s /usr/local/bin/gbase64    bin/base64
    run ln -s /usr/local/bin/gunlink    bin/unlink
    run ln -s /usr/local/bin/ginstall   bin/install
    run ln -s /usr/local/bin/grealpath  bin/realpath
    run ln -s /usr/local/bin/gsha256sum bin/sha256sum

    printf 'export ACLOCAL_PATH=/usr/local/share/aclocal\n' > init.sh
}

__setup_syspm_freebsd() {
    SYSPM=pkg

    #run $sudo pkg update || true
    run $sudo pkg install -y bash coreutils findutils gawk gsed gnugrep tree jq git curl libnghttp2 gcc

    run ln -s /usr/local/go122/bin/go   bin/go

    run ln -s /usr/local/bin/gln        bin/ln
    run ln -s /usr/local/bin/gm4        bin/m4
    run ln -s /usr/local/bin/gsed       bin/sed
    run ln -s /usr/local/bin/gawk       bin/awk
    run ln -s /usr/local/bin/ggrep      bin/grep
    run ln -s /usr/local/bin/gfind      bin/find
    run ln -s /usr/local/bin/gmake      bin/make
    run ln -s /usr/local/bin/gnustat    bin/stat
    run ln -s /usr/local/bin/gdate      bin/date
    run ln -s /usr/local/bin/gnproc     bin/nproc
    run ln -s /usr/local/bin/gbase64    bin/base64
    run ln -s /usr/local/bin/gunlink    bin/unlink
    run ln -s /usr/local/bin/ginstall   bin/install
    run ln -s /usr/local/bin/grealpath  bin/realpath
    run ln -s /usr/local/bin/gsha256sum bin/sha256sum

    printf 'export ACLOCAL_PATH=/usr/local/share/aclocal\n' > init.sh
}

__setup_syspm_openbsd() {
    SYSPM=pkg_add

    # pkg.m4 is in metaauto package, not in pkgconf package. metaauto package is usually depended by automake-1.16.3 package

    # https://man.openbsd.org/pkg_add
    run $sudo pkg_add bash coreutils findutils gawk gsed ggrep jq git curl libarchive gmake gcc%11

    run ln -s /usr/local/bin/python3.11 bin/python3

    run ln -s /usr/local/bin/gln        bin/ln
    run ln -s /usr/local/bin/gm4        bin/m4
    run ln -s /usr/local/bin/gsed       bin/sed
    run ln -s /usr/local/bin/gawk       bin/awk
    run ln -s /usr/local/bin/ghead      bin/head
    run ln -s /usr/local/bin/ggrep      bin/grep
    run ln -s /usr/local/bin/gfind      bin/find
    run ln -s /usr/local/bin/gmake      bin/make
    run ln -s /usr/local/bin/gstat      bin/stat
    run ln -s /usr/local/bin/gdate      bin/date
    run ln -s /usr/local/bin/gnproc     bin/nproc
    run ln -s /usr/local/bin/gbase64    bin/base64
    run ln -s /usr/local/bin/gunlink    bin/unlink
    run ln -s /usr/local/bin/ginstall   bin/install
    run ln -s /usr/local/bin/grealpath  bin/realpath
    run ln -s /usr/local/bin/gsha256sum bin/sha256sum
    run ln -s /usr/local/bin/pkgconf    bin/pkg-config

    # tree package in OpenBSD ports is https://github.com/pyr/tree
    # It is not compatible with the commonly used one https://github.com/Old-Man-Programmer/tree

    unset CC
    unset INSTALL
    unset CFLAGS
    unset LDLFAGS
    unset CPPFLAGS

    step "install tree utility"
    wfetch 'https://github.com/Old-Man-Programmer/tree/archive/refs/tags/2.2.1.tar.gz' -o tree.src.tar.gz --no-buffer
    run install -d tree.src
    run bsdtar  xf tree.src.tar.gz -C tree.src --strip-components=1
    run gmake   -C tree.src clean
    run gmake   -C tree.src install PREFIX="$PWD"

    cat > init.sh <<EOF
export AUTOCONF_VERSION=2.69
export AUTOMAKE_VERSION=1.16

export ACLOCAL_PATH=/usr/local/share/aclocal

PPFLAGS=-I/usr/local/include
LDFLAGS=-L/usr/local/lib
EOF
}

__setup_syspm_netbsd() {
    SYSPM=pkgin

    GREP=grep

    # NetBSD-10.0 grep report:
    # grep: Undefined PLT symbol "mbrtoc32" (symnum = 30)
    if [ "$(uname -r)" = '10.0' ] ; then
        unset GREP
    fi

    run $sudo pkgin -y update
    run $sudo pkgin -y install bash coreutils findutils gawk gsed "$GREP" git curl bsdtar tree jq gcc13 binutils ca-certificates

    # https://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/security/ca-certificates/index.html
    run $sudo /usr/pkg/sbin/update-ca-certificates --etccertsdir /etc/openssl/certs
    #export SSL_CERT_FILE='/etc/openssl/certs/ca-certificates.crt'

    # https://github.com/ebiggers/libdeflate/issues/387
    # https://github.com/NetBSD/pkgsrc/blob/trunk/lang/gcc13/Makefile.common#L90
    run $sudo ln -sf /usr/pkg/bin/gas /usr/bin/as
    run $sudo ln -sf /usr/pkg/bin/gld /usr/bin/ld

    run ln -s /usr/pkg/gcc13/bin/gcc  bin/gcc
    run ln -s /usr/pkg/gcc13/bin/g++  bin/g++
    run ln -s /usr/pkg/gcc13/bin/gfortran bin/gfortran

    run ln -s /usr/pkg/go124/bin/go   bin/go

    run ln -s /usr/pkg/bin/python3.12 bin/python3

    if [ -z "$GREP" ] ; then
        wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/grep-3.11-netbsd-10.0-amd64.release.tar.xz' --no-buffer
        run bsdtar xf grep-3.11-netbsd-10.0-amd64.release.tar.xz --strip-components=1
    fi

    cat > init.sh <<EOF
export PATH="/usr/pkg/gnu/bin:/usr/pkg/bin:\$PATH"
export ACLOCAL_PATH=/usr/pkg/share/aclocal
EOF
}

__setup_syspm() {
    step "install needed packages via your system's package manager"

    if [ "$NATIVE_PLATFORM_TYPE" = linux ] ; then
        unset ID

        if [ -f /etc/os-release ] ; then
            .   /etc/os-release
        fi

        NATIVE_PLATFORM_NAME="$ID"
    else
        NATIVE_PLATFORM_NAME="$NATIVE_PLATFORM_TYPE"
    fi

    __setup_syspm_$NATIVE_PLATFORM_NAME

    export PATH="$PWD/bin:$PATH"

    #################################################################################

    step "install ppkg core"
    run git clone --depth=1 https://github.com/leleliu008/ppkg

    if [ "$NATIVE_PLATFORM_TYPE" = macos ] ; then
        ELFTOOL_SRCS=
    else
        ELFTOOL_SRCS="$(ls ppkg/core/elftools/*.c)"
    fi

    for f in ppkg/core/*.c ppkg/core/wrappers/*.c $ELFTOOL_SRCS
    do
        o="${f##*/}"
        o="${o%.c}"

        run cc -flto -Os -std=c99 -o "$o" "$f"
        run strip "$o"
    done

    run mv ppkg/core/uppm-shim-$SYSPM uppm
    run mv ppkg/core/fonts.conf .

    run gsed -i "'s|PPKG_CORE_DIR|$PPKG_CORE_DIR|'" fonts.conf

    #################################################################################

    wfetch 'https://raw.githubusercontent.com/adobe-fonts/source-code-pro/release/OTF/SourceCodePro-Light.otf' --no-buffer

    #################################################################################

    if [ "$NATIVE_PLATFORM_TYPE" = linux ] ; then
        SRC=sysinfo/src/lib/determine-linux-system-libc.c
    else
        SRC=
    fi

    step "install sysinfo"
    run git clone --depth=1 https://github.com/leleliu008/sysinfo
    run cc -Os -flto -o bin/sysinfo sysinfo/src/main/sysinfo.c sysinfo/src/lib/sysinfo.c $SRC -Isysinfo/src/lib
    run strip bin/sysinfo
    run bin/sysinfo

    #################################################################################

    [ "$NATIVE_PLATFORM_TYPE" = macos ] || {
        step "install patchelf"
        wfetch 'https://github.com/NixOS/patchelf/archive/refs/tags/0.17.2.tar.gz' -o patchelf.src.tar.gz --no-buffer
        run install -d patchelf.src
        run bsdtar xf patchelf.src.tar.gz -C patchelf.src --strip-components=1
        run c++ -std=c++17 -Wall -D_FILE_OFFSET_BITS=64 -O3 -flto -o bin/patchelf patchelf.src/src/patchelf.cc
        run strip bin/patchelf
    }

    #################################################################################

    unset X

    case $NATIVE_PLATFORM_TYPE in
        linux)
            case $NATIVE_PLATFORM_ARCH in
                x86_64)  X='amd64' ;;
                aarch64) X='arm64' ;;
                loongarch64)
                         X='' ;;
                *)       X="$NATIVE_PLATFORM_ARCH"
            esac
            ;;
        freebsd|openbsd|netbsd)
            X="$NATIVE_PLATFORM_ARCH"
            ;;
    esac

    [ -n "$X" ] && {
        step "install yq"
        wfetch "https://github.com/mikefarah/yq/releases/download/v4.45.4/yq_${NATIVE_PLATFORM_TYPE}_$X" -o bin/yq --no-buffer
        run chmod +x bin/yq
    }

    #################################################################################

    # https://curl.se/docs/caextract.html
    wfetch 'https://curl.se/ca/cacert.pem' --no-buffer

    printf 'SYSPM=%s\n' "$SYSPM" >> init.sh
}

# use commands: uname curl|wget
__setup_uppm() {
    case $NATIVE_PLATFORM_TYPE in
        macos)
            NATIVE_PLATFORM_VERS="$(sw_vers -productVersion)"
            NATIVE_PLATFORM_VERS_MAJOR="${NATIVE_PLATFORM_VERS%%.*}"

            case $NATIVE_PLATFORM_VERS_MAJOR in
                10) NATIVE_PLATFORM_VERS='10.15' ;;
                11) NATIVE_PLATFORM_VERS='11.0'  ;;
                12) NATIVE_PLATFORM_VERS='12.0'  ;;
                13) NATIVE_PLATFORM_VERS='13.0'  ;;
                14) NATIVE_PLATFORM_VERS='14.0'  ;;
                *)  NATIVE_PLATFORM_VERS='15.0'  ;;
            esac
            ;;
        freebsd)
            case $(freebsd-version) in
                13.2) NATIVE_PLATFORM_VERS='13.2' ;;
                13.3) NATIVE_PLATFORM_VERS='13.3' ;;
                13.4) NATIVE_PLATFORM_VERS='13.4' ;;
                14.0) NATIVE_PLATFORM_VERS='14.0' ;;
                *)    NATIVE_PLATFORM_VERS='14.1' ;;
            esac
            ;;
        openbsd)
            case $(uname -r) in
                7.2) NATIVE_PLATFORM_VERS='7.2' ;;
                7.3) NATIVE_PLATFORM_VERS='7.3' ;;
                7.4) NATIVE_PLATFORM_VERS='7.4' ;;
                7.5) NATIVE_PLATFORM_VERS='7.5' ;;
                *)   NATIVE_PLATFORM_VERS='7.6' ;;
            esac
            ;;
        netbsd)
            case $(uname -r) in
                9.2) NATIVE_PLATFORM_VERS='9.2' ;;
                9.3) NATIVE_PLATFORM_VERS='9.3' ;;
                9.4) NATIVE_PLATFORM_VERS='9.4' ;;
                *)   NATIVE_PLATFORM_VERS='10.0' ;;
            esac
            ;;
        dragonflybsd)
            NATIVE_PLATFORM_VERS='6.4'
            ;;
    esac

    ##################################################################################

    if [ "$GITHUB_ACTIONS" = true ] || [ "$1" = -y ] ; then
        case $NATIVE_PLATFORM_TYPE in
            dragonflybsd)
                # libnghttp2 should also be installed, otherwise the following error will be shown
                # /usr/local/lib/libcurl.so.4: Undefined symbol "nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation"
                run $sudo pkg install -y curl libnghttp2
                ;;
            linux)
                unset ID

                if [ -f /etc/os-release ] ; then
                    .   /etc/os-release

                    case $ID in
                        alpine)
                            run $sudo /sbin/apk update
                            run $sudo /sbin/apk add g++ gfortran linux-headers
                            ;;
                        ubuntu|debian)
                            run $sudo /usr/bin/apt -y update
                            run $sudo /usr/bin/apt -y install curl g++ gfortran linux-headers-generic
                            ;;
                        openEuler)
                            run $sudo /usr/bin/dnf -y update
                            run $sudo /usr/bin/dnf -y install curl gcc-c++ gcc-gfortran
                            ;;
                        arch)
                            run $sudo /sbin/pacman -Syy --noconfirm
                            run $sudo /sbin/pacman -S   --noconfirm curl gcc base-devel
                            ;;
                    esac
                fi
        esac
    fi

    ##################################################################################

    if [ -z "$NATIVE_PLATFORM_VERS" ] ; then
        NATIVE_PLATFORM_TARGET="$NATIVE_PLATFORM_TYPE-$NATIVE_PLATFORM_ARCH"
    else
        NATIVE_PLATFORM_TARGET="$NATIVE_PLATFORM_TYPE-$NATIVE_PLATFORM_VERS-$NATIVE_PLATFORM_ARCH"
    fi

    ##################################################################################

    # https://curl.se/docs/caextract.html
    wfetch 'https://curl.se/ca/cacert.pem' --no-buffer

    export SSL_CERT_FILE="$PWD/cacert.pem"

    ##################################################################################

    PPKG_CORE_RELEASE_VERSION='2025.07.18'
    PPKG_CORE_RELEASE_TAG="ppkg-core-$PPKG_CORE_RELEASE_VERSION"
    PPKG_CORE_RELEASE_TARBALL_FILENAME="$PPKG_CORE_RELEASE_TAG-$NATIVE_PLATFORM_TARGET.tar.xz"
    PPKG_CORE_RELEASE_TARBALL_URL="https://github.com/leleliu008/ppkg/releases/download/$PPKG_CORE_RELEASE_TAG/$PPKG_CORE_RELEASE_TARBALL_FILENAME"

    wfetch "$PPKG_CORE_RELEASE_TARBALL_URL" --no-buffer

    ##################################################################################

    BSDTAR="$(command -v bsdtar || true)"

    if [ -n "$BSDTAR" ] ; then
        TAR="$BSDTAR"
    else
        TAR="$(command -v gtar || command -v tar || true)"

        if [ -n "$TAR" ] && command -v xz > /dev/null ; then
            :
        else
            wfetch "https://github.com/leleliu008/bsdtar.exe/releases/download/2025.06.26/bsdtar-3.7.7-$NATIVE_PLATFORM_TARGET.release" -o bsdtar --no-buffer
            chmod +x bsdtar
            TAR=./bsdtar
        fi
    fi

    ##################################################################################

    run "$TAR" xvf "$PPKG_CORE_RELEASE_TARBALL_FILENAME" --strip-components=1 --no-same-owner

    ##################################################################################

    #run ./uppm about
    run ./uppm update

    unset UPPM_PACKAGE_EXEFIND_PATH
    unset UPPM_PACKAGE_ACLOCAL_PATH

    if ./uppm is-available bat ; then
        BAT=bat
    else
        BAT=
    fi

    if ./uppm is-available dot_static ; then
        DOT=dot_static
    else
        DOT=
    fi

    for UPPM_PACKAGE_NAME in bash coreutils findutils gawk gsed grep bsdtar git curl tree sysinfo fzf jq yq d2 $DOT $BAT
    do
        run ./uppm install "$UPPM_PACKAGE_NAME"

        UPPM_PACKAGE_INSTALLED_DIR="$UPPM_HOME/installed/$UPPM_PACKAGE_NAME"

        if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/bin" ] ; then
            UPPM_PACKAGE_EXEFIND_PATH="$UPPM_PACKAGE_EXEFIND_PATH:$UPPM_PACKAGE_INSTALLED_DIR/bin"
        fi

        if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            UPPM_PACKAGE_EXEFIND_PATH="$UPPM_PACKAGE_EXEFIND_PATH:$UPPM_PACKAGE_INSTALLED_DIR/sbin"
        fi

        if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then
            UPPM_PACKAGE_ACLOCAL_PATH="$UPPM_PACKAGE_ACLOCAL_PATH:$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal"
        fi
    done

    UPPM_PACKAGE_EXEFIND_PATH="${UPPM_PACKAGE_EXEFIND_PATH#':'}"
    UPPM_PACKAGE_ACLOCAL_PATH="${UPPM_PACKAGE_ACLOCAL_PATH#':'}"

    ##################################################################################

    run "$UPPM_HOME/installed/gsed/bin/gsed" -i "'s|PPKG_CORE_DIR|$PPKG_CORE_DIR|'" fonts.conf

    ##################################################################################

    cat > init.sh <<EOF
export ACLOCAL_PATH="$UPPM_PACKAGE_ACLOCAL_PATH:\$ACLOCAL_PATH"
export PATH="$UPPM_PACKAGE_EXEFIND_PATH:\$PATH"

# https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables
if [ -d "\$UPPM_HOME/installed/git/libexec/git-core" ] ; then
    export GIT_EXEC_PATH="\$UPPM_HOME/installed/git/libexec/git-core"
    export GIT_TEMPLATE_DIR="\$UPPM_HOME/installed/git/share/git-core/templates"
    export GIT_CONFIG_NOSYSTEM=1
fi
EOF

    ##################################################################################

    if false ; then
        run install -d gcc
        wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/gcc-13.3.0-linux-glibc-x86_64.release.tar.xz' --no-buffer
        run $TAR xf gcc-*.tar.xz -C gcc --strip-components=1

        run install -d binutils
        wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/binutils-2.43.1-linux-glibc-x86_64.release.tar.xz' --no-buffer
        run $TAR xf binutils-*.tar.xz -C binutils --strip-components=1

        run install -d mold
        wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/mold-2.34.1-linux-glibc-x86_64.release.tar.xz' --no-buffer
        run $TAR xf mold-*.tar.xz -C mold --strip-components=1

        install -d bin
        #ln -sf ../mold/bin/mold bin/ld

        for item in addr2line ar as ld nm objdump readelf strip objcopy ranlib size strings
        do
            ln -sf ../binutils/bin/$item bin/$item
        done

        run install -d sysroot
        wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/glibc-2.40-linux-glibc-x86_64.tar.xz' --no-buffer
        run $TAR xf glibc-2.40-linux-glibc-x86_64.tar.xz -C sysroot --strip-components=1

        wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/linux-headers-6.8-linux-x86_64.tar.xz' --no-buffer
        run $TAR xf linux-headers-6.8-linux-x86_64.tar.xz -C sysroot --strip-components=1

        ln -s gcc/x86_64-pc-linux-gnu/13.1.0/libgcc.a gcc/lib/libgcc.a

        "$UPPM_HOME/installed/gsed/bin/gsed" -i "s|/home/leleliu008/.ppkg/installed/linux-glibc-x86_64/bebfceb3d2ea2461fde461b6c32a3e3cafc29d18ecec16e136e32b175caab53d|$PPKG_HOME/core/sysroot|g" sysroot/lib/libc.so sysroot/lib/libm.a sysroot/lib/libm.so

        mv gcc/bin/gcc gcc/bin/gcc.exe
        mv gcc/bin/g++ gcc/bin/g++.exe

        cat > gcc/bin/gcc <<EOF
#!/bin/sh
exec "$PPKG_HOME/core/gcc/bin/gcc.exe" "\$@" -specs "$PPKG_HOME/core/gcc.specs"
EOF
        cat > gcc/bin/g++ <<EOF
#!/bin/sh
exec "$PPKG_HOME/core/gcc/bin/g++.exe" "\$@" -specs "$PPKG_HOME/core/g++.specs"
EOF
        chmod +x gcc/bin/gcc
        chmod +x gcc/bin/g++

        # https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html
        cat > gcc.specs <<EOF
%rename cpp_options old_cpp_options

*cpp_options:
-nostdinc -isystem $PPKG_HOME/core/sysroot/include -isystem include%s %(old_cpp_options)

*cc1:
%(cc1_cpu) -nostdinc -isystem $PPKG_HOME/core/sysroot/include -isystem include%s

*link_libgcc:
-L$PPKG_HOME/core/sysroot/lib -L .%s

*libgcc:
libgcc.a%s %:if-exists(libgcc_eh.a%s)

*startfile:
%{!shared: $PPKG_HOME/core/sysroot/lib/Scrt1.o} $PPKG_HOME/core/sysroot/lib/crti.o crtbeginS.o%s

*endfile:
crtendS.o%s $PPKG_HOME/core/sysroot/lib/crtn.o

*link:
-dynamic-linker $PPKG_HOME/core/sysroot/lib/ld-linux-x86-64.so.2 -rpath $PPKG_HOME/core/sysroot/lib -rpath $PPKG_HOME/core/gcc/lib -L $PPKG_HOME/core/sysroot/lib -L $PPKG_HOME/core/gcc/lib -nostdlib %{shared:-shared} %{static:-static} %{rdynamic:-export-dynamic}

*esp_link:


*esp_options:


*esp_cpp_options:


EOF

        cat > g++.specs <<EOF
%rename cpp_options old_cpp_options

*cpp_options:
-nostdinc -isystem $PPKG_HOME/core/sysroot/include -I $PPKG_HOME/core/include/c++/13.1.0 -I $PPKG_HOME/core/include/c++/13.1.0/x86_64-pc-linux-gnu -isystem include%s %(old_cpp_options)

*cc1:
%(cc1_cpu) -nostdinc -isystem $PPKG_HOME/core/sysroot/include -I $PPKG_HOME/core/include/c++/13.1.0 -I $PPKG_HOME/core/include/c++/13.1.0/x86_64-pc-linux-gnu -isystem include%s

*link_libgcc:
-L$PPKG_HOME/core/sysroot/lib -L .%s

*libgcc:
libgcc.a%s %:if-exists(libgcc_eh.a%s)

*startfile:
%{!shared: $PPKG_HOME/core/sysroot/lib/Scrt1.o} $PPKG_HOME/core/sysroot/lib/crti.o crtbeginS.o%s

*endfile:
crtendS.o%s $PPKG_HOME/core/sysroot/lib/crtn.o

*link:
-dynamic-linker $PPKG_HOME/core/sysroot/lib/ld-linux-x86-64.so.2 -rpath $PPKG_HOME/core/sysroot/lib -rpath $PPKG_HOME/core/gcc/lib -L $PPKG_HOME/core/sysroot/lib -L $PPKG_HOME/core/gcc/lib -nostdlib %{shared:-shared} %{static:-static} %{rdynamic:-export-dynamic}

*esp_link:


*esp_options:


*esp_cpp_options:


EOF

        for item in gcc g++ c++ cpp
        do
            ln -sf ../gcc/bin/$item bin/$item
        done

        ln -s ../wrapper-native-cc bin/cc
    fi
}

__setup() {
    SESSION_DIR="$PPKG_HOME/run/$$/core"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    run install -d bin lib

    #################################################

    unset NATIVE_PLATFORM_KIND
    unset NATIVE_PLATFORM_TYPE
    unset NATIVE_PLATFORM_ARCH
    unset NATIVE_PLATFORM_VERS

    NATIVE_PLATFORM_KIND="$(uname -s | tr A-Z a-z)"
    NATIVE_PLATFORM_ARCH="$(uname -m)"

    case $NATIVE_PLATFORM_KIND in
        dragonfly)  NATIVE_PLATFORM_TYPE=dragonflybsd ;;
        darwin)     NATIVE_PLATFORM_TYPE=macos ;;
        *)          NATIVE_PLATFORM_TYPE="$NATIVE_PLATFORM_KIND" ;;
    esac

    #################################################

    case $NATIVE_PLATFORM_KIND in
        freebsd)
            printf 'INPUT(-lc++)\n' > lib/libstdc++.a
            ;;
        openbsd)
            printf 'INPUT(-lc)\n'   > lib/libdl.a
            printf 'INPUT(-lc)\n'   > lib/librt.a
            printf 'INPUT(-lc)\n'   > lib/libcrypt.a
            printf 'INPUT(-lc++)\n' > lib/libstdc++.a
            ;;
         netbsd)
            printf 'INPUT(-lc)\n'      > lib/libdl.a
            printf 'INPUT(-lstdc++)\n' > lib/libc++.a
            ;;
    esac

    #################################################

    unset sudo

    [ "$(id -u)" -eq 0 ] || sudo=sudo

    #################################################

    if [ "$1" = '--syspm' ] ; then
        __setup_syspm
    else
        __setup_uppm
    fi

    #################################################

    if [ -d        "$PPKG_CORE_DIR" ] ; then
        run rm -rf "$PPKG_CORE_DIR"
    fi

    run mv "$SESSION_DIR" "$PPKG_HOME/"

    success "ppkg has been set up successfully."
}

# }}}
##############################################################################
# {{{ ppkg help

__help() {
    cat <<EOF
[38;5;204m    [38;5;198m    [38;5;199m     [38;5;163m_   [38;5;164m    [38;5;128m  
[38;5;204m _ [38;5;198m__  _[38;5;199m __ [38;5;163m| | [38;5;164m____ [38;5;128m_ 
[38;5;204m| '[38;5;198m_ \|[38;5;199m '_ \[38;5;163m| |/[38;5;164m / _[38;5;128m\` |
[38;5;204m| |[38;5;198m_) |[38;5;199m |_)[38;5;163m |   [38;5;164m< (_[38;5;128m| |
[38;5;204m| [38;5;198m.__/[38;5;199m| .__[38;5;163m/|_|[38;5;164m\_\_[38;5;128m_, |
[38;5;204m|_[38;5;198m|   [38;5;199m|_| [38;5;163m     [38;5;164m  |_[38;5;128m__/  $PPKG_VERSION
[0m
EOF

    printf '%b\n' "\
${COLOR_GREEN}A portable package builder/manager for UNIX-like systems.${COLOR_OFF}

${COLOR_GREEN}ppkg <ACTION> [ARGUMENT...]${COLOR_OFF}

${COLOR_GREEN}ppkg help${COLOR_OFF}
${COLOR_GREEN}ppkg --help${COLOR_OFF}
${COLOR_GREEN}ppkg -h${COLOR_OFF}
    show help of this command.

${COLOR_GREEN}ppkg version${COLOR_OFF}
${COLOR_GREEN}ppkg --version${COLOR_OFF}
${COLOR_GREEN}ppkg -V${COLOR_OFF}
    show version of this command.

${COLOR_GREEN}ppkg setup${COLOR_OFF}
    install essential tools (e.g. uppm, bash, coreutils, findutils, gawk, gsed, grep, git, curl, bsdtar, tree, fzf, bat, jq, yq, d2, etc) used by this shell script.

${COLOR_GREEN}ppkg about${COLOR_OFF}
    show basic information about this software.

${COLOR_GREEN}ppkg sysinfo${COLOR_OFF}
    show basic information about your current running operation system.

${COLOR_GREEN}ppkg gen-url-transform-sample${COLOR_OFF}
    generate url-transform sample.

${COLOR_GREEN}ppkg integrate zsh [--output-dir=<DIR>]${COLOR_OFF}
    download a zsh-completion script file to a approprivate location.

${COLOR_GREEN}ppkg update${COLOR_OFF}
    update all the available formula repositories.

${COLOR_GREEN}ppkg upgrade-self${COLOR_OFF}
    upgrade this software.

${COLOR_GREEN}ppkg cleanup${COLOR_OFF}
    delete the unused cached files.


${COLOR_GREEN}ppkg ls-available${COLOR_OFF}
    list all the available packages.

${COLOR_GREEN}ppkg ls-installed${COLOR_OFF}
    list all the installed packages.

${COLOR_GREEN}ppkg ls-outdated${COLOR_OFF}
    list all the outdated  packages.


${COLOR_GREEN}ppkg is-available <PACKAGE-NAME>${COLOR_OFF}
    check if the given package is available

${COLOR_GREEN}ppkg is-installed <PACKAGE-SPEC>${COLOR_OFF}
    check if the given package is installed

${COLOR_GREEN}ppkg is-outdated  <PACKAGE-SPEC>${COLOR_OFF}
    check if the given package is outdated


${COLOR_GREEN}ppkg formula-repo-init <FORMULA-REPO-NAME> <FORMULA-REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable]${COLOR_OFF}
    create a new empty formula repository.

${COLOR_GREEN}ppkg formula-repo-add  <FORMULA-REPO-NAME> <FORMULA-REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable]${COLOR_OFF}
    create a new empty formula repository then sync with server.

${COLOR_GREEN}ppkg formula-repo-del  <FORMULA-REPO-NAME>${COLOR_OFF}
    delete the given formula repository.

${COLOR_GREEN}ppkg formula-repo-sync <FORMULA-REPO-NAME>${COLOR_OFF}
    update the given formula repository.

${COLOR_GREEN}ppkg formula-repo-info <FORMULA-REPO-NAME>${COLOR_OFF}
    show information of the given formula repository.

${COLOR_GREEN}ppkg formula-repo-conf <FORMULA-REPO-NAME> [--url=VALUE --branch=VALUE --pin/--unpin --enable/--disable]${COLOR_OFF}
    change the config of the given formula repository.

${COLOR_GREEN}ppkg formula-repo-list${COLOR_OFF}
    list all available formula repositories.


${COLOR_GREEN}ppkg search <REGULAR-EXPRESSION-PARTTEN>${COLOR_OFF}
    search all available packages whose name matches the given regular expression partten.


${COLOR_GREEN}ppkg info-available <PACKAGE-NAME> [--json | --yaml | <KEY>]${COLOR_OFF}
    show information of the given available package.

${COLOR_GREEN}ppkg info-installed <PACKAGE-SPEC> [--json | --yaml | <KEY>]${COLOR_OFF}
    show information of the given installed package.


${COLOR_GREEN}ppkg depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>] [--engine=<d2|dot>]${COLOR_OFF}
    show the packages that are depended by the given package.

    <OUTPUT-TYPE> should be any one of d2 dot box svg png

    <OUTPUT-PATH> can be either the filepath or directory.

    If <OUTPUT-PATH> is . .. or ends with slash(/), then it will be treated as a directory, otherwise, it will be treated as a filepath.

    If <OUTPUT-PATH> is treated as a directory, then it will be expanded to <OUTPUT-PATH>/<PACKAGE-NAME>-dependencies.<OUTPUT-TYPE>

    If -o <OUTPUT-PATH> option is unspecified, the result will be written to stdout.

    If -t <OUTPUT-TYPE> option is unspecified, and if <OUTPUT-PATH> ends with one of .d2 .dot .box .svg .png, <OUTPUT-TYPE> will be the <OUTPUT-PATH> suffix, otherwise, <OUTPUT-TYPE> will be box.

    You are allowd to choose the diagram engine for generating svg/png format diagram. ppkg only support d2 and dot diagram engine at the moment.

${COLOR_GREEN}ppkg fetch <PACKAGE-NAME>${COLOR_OFF}
    download all the resources of the given package to the local cache.


${COLOR_GREEN}ppkg install <PACKAGE-NAME|PACKAGE-SPEC>... [INSTALL-OPTIONS]${COLOR_OFF}
    install the given packages.

    ${COLOR_RED}C and C++ compiler for native build should be installed by yourself using your system's default package manager before running this command.${COLOR_OFF}

    <PACKAGE-NAME> should match the regular expression pattern ${COLOR_RED}^[A-Za-z0-9+-_.@]{1,50}$ ${COLOR_OFF}

    <PACKAGE-SPEC> is a formatted string that has form ${COLOR_RED}<TARGET>/<PACKAGE-NAME>${COLOR_OFF}

    <TARGET> indicates which platform would be built for.

    <TARGET> is a formatted string that has form ${COLOR_RED}<PLATFORM-NAME>-<PLATFORM-VERSION>-<PLATFORM-ARCH>${COLOR_OFF}

    <PLATFORM-NAME> : e.g. linux, macos, freebsd, openbsd, netbsd, dragonflybsd, etc

    <PLATFORM-VERSION> : specify the platform version to be built with. It usually matches the regular expression pattern '[0-9][0-9]?.[0-9][0-9]?', e.g. 10.15, 11.0, 12.0, 12.6, etc.

    <PLATFORM-ARCH> : e.g. x86_64, amd64, arm64, aarch64, riscv64, ppc64le, s390x, etc

    <TARGET> examples:
        linux-glibc-x86_64
        linux-glibc-aarch64
        linux-glibc-riscv64
        linux-glibc-ppc64le
        linux-glibc-s390x

        linux-musl-x86_64
        linux-musl-aarch64
        linux-musl-riscv64
        linux-musl-ppc64le
        linux-musl-s390x

        macos-13.0-x86_64
        macos-12.0-arm64

        dragonflybsd-6.4-x86_64

        freebsd-13.2-amd64
        openbsd-7.4-amd64
        netbsd-9.1-amd64

    INSTALL-OPTIONS:
        ${COLOR_BLUE}--target=<TARGET>${COLOR_OFF}
            specify the target to be built for.

            If this option is unspecified, the environment variable ${COLOR_RED}PPKG_DEFAULT_TARGET${COLOR_OFF} is honored, if the environment variable PPKG_DEFAULT_TARGET is not set, <TARGET> will be same as your current running operation system.

        ${COLOR_BLUE}--profile=<debug|release>${COLOR_OFF}
            specify the build profile.

            debug:
                  CFLAGS: -O0 -g
                CXXFLAGS: -O0 -g

            release:
                  CFLAGS: -Os
                CXXFLAGS: -Os
                CPPFLAGS: -DNDEBUG
                 LDFLAGS: -flto -Wl,-s

        ${COLOR_BLUE}--static${COLOR_OFF}
            create Fully Statically Linked Executables

            This option only affects the package whose type is exe. If this option is not given, ppkg will create Mostly Statically Linked Executables

            a  fully statically linked executable is a executable that without any additional libraries to be loaded at runtime.
            a mostly statically linked executable is a executable that without any additional libraries except libc.so, libm.so, libdl.so, libpthread.so, etc.

            a fully  statically linked executable is easy to distribute and deploy especially on different GNU/Linux systems.
            a mostly statically linked executable is easy to distribute and deploy especially on macOS.

        ${COLOR_BLUE}-j <N>${COLOR_OFF}
            specify the number of jobs you can run in parallel.

        ${COLOR_BLUE}-I <FORMULA-SEARCH-DIR>${COLOR_OFF}
            specify the formula search directory. This option can be used multiple times.

        ${COLOR_BLUE}-E${COLOR_OFF}
            export compile_commands.json

        ${COLOR_BLUE}-U${COLOR_OFF}
            upgrade packages if possible.

        ${COLOR_BLUE}-K${COLOR_OFF}
            keep the session directory even if this package is successfully installed.

        ${COLOR_BLUE}-q${COLOR_OFF}
            silent mode. no any messages will be output to terminal.

        ${COLOR_BLUE}-v${COLOR_OFF}
            verbose mode. many messages will be output to terminal.

            This option is equivalent to -v-* options all are supplied.

        ${COLOR_BLUE}-x${COLOR_OFF}
            very verbose mode. many many messages will be output to terminal.

            This option is equivalent to -v-* and -x-* options all are supplied.

        ${COLOR_BLUE}-v-env${COLOR_OFF}
            show all environment variables before starting to build.

        ${COLOR_BLUE}-v-http${COLOR_OFF}
            show http request/response.

        ${COLOR_BLUE}-v-toolchain${COLOR_OFF}
            show C/C++ toolchain information.

        ${COLOR_BLUE}-v-formula${COLOR_OFF}
            show formula content.

        ${COLOR_BLUE}-v-go${COLOR_OFF}
            pass -v argument to go build command.

        ${COLOR_BLUE}-v-uppm${COLOR_OFF}
            pass -v argument to uppm command.

        ${COLOR_BLUE}-v-cargo${COLOR_OFF}
            pass -v argument to cargo command.

        ${COLOR_BLUE}-v-meson${COLOR_OFF}
            pass -v argument to meson command.

        ${COLOR_BLUE}-v-ninja${COLOR_OFF}
            pass -v argument to ninja command.

        ${COLOR_BLUE}-v-gmake${COLOR_OFF}
            pass V=1 argument to gmake command.

        ${COLOR_BLUE}-v-cmake${COLOR_OFF}
            set(CMAKE_VERBOSE_MAKEFILE ON)

        ${COLOR_BLUE}-v-xmake${COLOR_OFF}
            pass -v argument to xmake command.

        ${COLOR_BLUE}-x-sh${COLOR_OFF}
            set -x to debug current running shell.

        ${COLOR_BLUE}-x-cc${COLOR_OFF}
            pass -v argument to clang command.

        ${COLOR_BLUE}-x-ld${COLOR_OFF}
            pass -Wl,-v argument to linker.

        ${COLOR_BLUE}-x-go${COLOR_OFF}
            pass -x argument to go build command.

        ${COLOR_BLUE}-x-cargo${COLOR_OFF}
            pass -vv argument to cargo command.

        ${COLOR_BLUE}-x-gmake${COLOR_OFF}
            pass --debug argument to gmake command.

        ${COLOR_BLUE}-x-cmake${COLOR_OFF}
            set(CMAKE_FIND_DEBUG_MODE ON)

        ${COLOR_BLUE}-x-xmake${COLOR_OFF}
            pass -vD argument to xmake command.

        ${COLOR_BLUE}-x-pkg-config${COLOR_OFF}
            export PKG_CONFIG_DEBUG_SPEW=1

        ${COLOR_BLUE}--disable-ccache${COLOR_OFF}
            do not use ccache.


${COLOR_GREEN}ppkg reinstall <PACKAGE-SPEC>... [INSTALL-OPTIONS]${COLOR_OFF}
    reinstall the given packages.

${COLOR_GREEN}ppkg upgrade   <PACKAGE-SPEC>... [INSTALL-OPTIONS]${COLOR_OFF}
    upgrade the given packages or all outdated packages.

${COLOR_GREEN}ppkg uninstall <PACKAGE-SPEC>...${COLOR_OFF}
    uninstall the given packages.


${COLOR_GREEN}ppkg tree <PACKAGE-SPEC> [-a | --dirsfirst | -L N]${COLOR_OFF}
    list installed files of the given installed package in a tree-like format.

${COLOR_GREEN}ppkg logs <PACKAGE-SPEC>${COLOR_OFF}
    show logs of the given installed package.

    This will launch fzf finder. press ESC key to quit.

${COLOR_GREEN}ppkg bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE> [--exclude <PATH>] [-K] [--portable] [--sign] [--sign-key=<SIGNKEY>] [--] [mksquashfs OPTIONS]${COLOR_OFF}
    bundle the given installed package into a single archive file.

    ${COLOR_BLUE}<OUTPUT-DIR>${COLOR_OFF}
        If specified, should end with slash.

    ${COLOR_BLUE}<OUTPUT-FILENAME-PREFIX>${COLOR_OFF}
        If unspecified, use <PACKAGE-NAME>-<PACKAGE-VERSION>-<TARGET-PLATFORM-NAME>-<TARGET-PLATFORM-VERSION>-<TARGET-PLATFORM-ARCH> as default.

    ${COLOR_BLUE}<BUNDLE-TYPE>${COLOR_OFF}
        should be any one of .tar.gz .tar.xz .tar.lz .tar.bz2 .zip .AppImage

    ${COLOR_BLUE}--exclude <PATH>${COLOR_OFF}
        exclude file that is not mean to be bundled into the final file.

        <PATH> is relative to the installed root directory.

        this option can be used multiple times.

    ${COLOR_BLUE}-K${COLOR_OFF}
        keep the session directory even if this package is successfully bundled.

    ${COLOR_BLUE}--portable${COLOR_OFF}
        this option only has effect for linux to bundle libc and dynamic loader into the final file to make it portable to run on any linux.

    ${COLOR_BLUE}--sign${COLOR_OFF}
        sign the output file with gpg.

    ${COLOR_BLUE}--sign-key=<SIGNKEY>${COLOR_OFF}
        specify the gpg sign key.

    ${COLOR_BLUE}--${COLOR_OFF}
        options after -- would be passed to mksquashfs command only if <BUNDLE-TYPE> is .AppImage, otherwise, options after -- would be ignored.


${COLOR_GREEN}ppkg export <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<EXPORT-TYPE> [--exclude <PATH>] [-K]${COLOR_OFF}
    export the given installed package as another package format.

    ${COLOR_BLUE}<OUTPUT-DIR>${COLOR_OFF}
        If specified, should end with slash.

    ${COLOR_BLUE}<OUTPUT-FILENAME-PREFIX>${COLOR_OFF}
        If unspecified, use <PACKAGE-NAME>-<PACKAGE-VERSION>-<TARGET-PLATFORM-NAME>-<TARGET-PLATFORM-VERSION>-<TARGET-PLATFORM-ARCH> as default.

    ${COLOR_BLUE}<EXPORT-TYPE>${COLOR_OFF}
        should be any one of .deb .rpm .apk .pkg.tar.xz

    ${COLOR_BLUE}--exclude <PATH>${COLOR_OFF}
        exclude file that is not mean to be bundled into the final file.

        <PATH> is relative to the installed root directory.

        this option can be used multiple times.

    ${COLOR_BLUE}-K${COLOR_OFF}
        keep the session directory even if this package is successfully bundled.

    ${COLOR_RED}Caveats:${COLOR_OFF}
        .deb format only can be run on Debian GNU Linux and it's derivatives.
        .rpm format only can be run on RHEL/CentOS/Fedora/openSUSE Linux and their derivatives.
        .pkg format only can be run on Arch Linux and it's derivative.
        .apk format only can be run on Alpine Linux and it's derivative.
"
}

# }}}
##############################################################################
# {{{ ppkg main

set -e

# If IFS is not set, the default value will be <space><tab><newline>
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_03
unset IFS

##################################################################################

if [ -n "$PPKG_XTRACE" ] ; then
    set -x
fi

[ -z "$PPKG_HOME" ] && {
    if [ -z "$HOME" ] ; then
        abort 1 "HOME environment variable is not set."
    else
        PPKG_HOME="$HOME/.ppkg"
    fi
}

PPKG_VERSION=0.23.31

PPKG_ARG0="$0"
PPKG_ARG1="$1"
PPKG_ARGV="$0 $*"

PPKG_PATH="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")"

PPKG_UPGRAGE_URL='https://raw.githubusercontent.com/leleliu008/ppkg/master/ppkg'
PPKG_OFFICIAL_FORMULA_REPO_URL='https://github.com/leleliu008/ppkg-formula-repository-official-core.git'
PPKG_ZSH_COMPLETION_SCRIPT_URL='https://raw.githubusercontent.com/leleliu008/ppkg/master/ppkg-zsh-completion'

PPKG_FORMULA_REPO_ROOT="$PPKG_HOME/repos.d"
PPKG_PACKAGE_INSTALLED_ROOT="$PPKG_HOME/installed"
PPKG_PACKAGE_SYMLINKED_ROOT="$PPKG_HOME/symlinked"
PPKG_DOWNLOADS_DIR="$PPKG_HOME/downloads"
PPKG_BACKUP_DIR="$PPKG_HOME/backup.d"

PPKG_CORE_DIR="$PPKG_HOME/core"

PPKG_SYSROOT="$PPKG_HOME/sysroot"

NATIVE_PACKAGE_INSTALLED_ROOT="$PPKG_HOME/native"

##################################################################################

# https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_default_verify_paths.html
if [ -f "$PPKG_CORE_DIR/cacert.pem" ] ; then
    export SSL_CERT_FILE="$PPKG_CORE_DIR/cacert.pem"
fi

##################################################################################

# dot_static command use this
# https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
if [ -z  "$FONTCONFIG_FILE" ] ; then
    export FONTCONFIG_FILE="$PPKG_CORE_DIR/fonts.conf"
fi

##################################################################################

UPPM="$PPKG_CORE_DIR/uppm"

export UPPM_HOME="$PPKG_HOME/uppm"

if [ -n  "$PPKG_URL_TRANSFORM" ] ; then
    export UPPM_URL_TRANSFORM="$PPKG_URL_TRANSFORM"
    export      URL_TRANSFORM="$PPKG_URL_TRANSFORM"
fi

##################################################################################

TIMESTAMP_UNIX="$(date +%s)"

##################################################################################

export BAT_THEME=Dracula

##################################################################################

unset SYSPM

unset STEP_NUM

##################################################################################

case $1 in
    ''|help|--help|-h)
        __help
        exit
        ;;
    version|--version|-V)
        printf '%s\n' "$PPKG_VERSION"
        exit
        ;;
    setup)
        shift
        __setup "$@"
        exit
        ;;
    gen-url-transform-sample)
        shift
        __gen_url_transform_sample "$@"
        exit
        ;;
     about)
        if command -v bat > /dev/null ; then
            VIEWER='bat --language=yaml --paging=never --color=always --theme=Dracula --style=plain'
        else
            VIEWER=cat
        fi

        $VIEWER <<EOF
ppkg.version : $PPKG_VERSION
ppkg.homedir : $PPKG_HOME
ppkg.exepath : $PPKG_PATH
ppkg.website : https://github.com/leleliu008/ppkg
EOF
        if [ -f "$UPPM" ] ; then
            printf '\n'
            "$UPPM" about
        fi

        exit
        ;;
esac

#########################################################################################

if [ -z "$CARGO_HOME" ] ; then
    bppend_to_PATH "$HOME/.cargo/bin"
else
    bppend_to_PATH "$CARGO_HOME/bin"
fi

# pip install --user <PKG>
bppend_to_PATH "$HOME/.local/bin"

# cpan install to default local location
bppend_to_PATH "$HOME/perl5/bin"

#########################################################################################

unset ACLOCAL_PATH

unset PKG_CONFIG_PATH
unset PKG_CONFIG_LIBDIR

unset CCFLAGS
unset XXFLAGS
unset PPFLAGS
unset LDFLAGS

#########################################################################################

if [ -f "$PPKG_CORE_DIR/init.sh" ] ; then
    .   "$PPKG_CORE_DIR/init.sh"
else
    abort 1 "please run ${COLOR_GREEN}$PPKG_ARG0 setup${COLOR_OFF} command first, then try again."
fi

#########################################################################################

# https://www.gnu.org/software/automake/manual/html_node/Macro-Search-Path.html
if [ -z  "$ACLOCAL_PATH" ] ; then
    export ACLOCAL_PATH="$PPKG_CORE_DIR/share/aclocal"
else
    export ACLOCAL_PATH="$PPKG_CORE_DIR/share/aclocal:$ACLOCAL_PATH"
fi

bppend_to_PATH "$PPKG_CORE_DIR/bin"

#########################################################################################

NATIVE_PLATFORM_KIND="$(sysinfo kind)"
NATIVE_PLATFORM_TYPE="$(sysinfo type)"
NATIVE_PLATFORM_CODE="$(sysinfo code)"
NATIVE_PLATFORM_NAME="$(sysinfo name)"
NATIVE_PLATFORM_VERS="$(sysinfo vers)"
NATIVE_PLATFORM_ARCH="$(sysinfo arch)"
NATIVE_PLATFORM_NCPU="$(sysinfo ncpu)"
NATIVE_PLATFORM_LIBC="$(sysinfo libc)"
NATIVE_PLATFORM_EUID="$(id -u)"
NATIVE_PLATFORM_EGID="$(id -g)"

TARGET_PLATFORM_NAME="$NATIVE_PLATFORM_TYPE"
TARGET_PLATFORM_ARCH="$NATIVE_PLATFORM_ARCH"

if [ "$NATIVE_PLATFORM_EUID" -ne 0 ] ; then
    sudo=sudo
fi

#########################################################################################

case $1 in
    sysinfo) shift; sysinfo "$@" ;;

    update)            shift; __sync_available_formula_repositories "$@" ;;
    formula-repo-list) shift; __list_available_formula_repositories "$@" ;;
    formula-repo-info) shift; __info_the_given_formula_repository "$@" ;;
    formula-repo-conf) shift; __conf_the_given_formula_repository "$@" ;;
    formula-repo-sync) shift; __sync_the_given_formula_repository "$@" ;;
    formula-repo-init)
        shift

        case $1 in
            official-*) abort 1 "ppkg formula repository name that starts with 'official-' is reserved for ppkg official formula repository, please use other name."
        esac

        __create_a_formula_repository "$@"
        ;;
    formula-repo-add)
        shift

        case $1 in
            official-*) abort 1 "ppkg formula repository name that starts with 'official-' is reserved for ppkg official formula repository, please use other name."
        esac

        __create_a_formula_repository_then_sync_it "$@"
        ;;
    formula-repo-del)
        shift
        __delete_a_formula_repository "$@"
        ;;

    info-available) shift; __info_the_given_available_package "$@" ;;
    info-installed) shift; __info_the_given_installed_package "$@" ;;

    ls-available) shift; __list_available_packages "$@" ;;
    ls-installed) shift; __list_installed_packages "$@" ;;
    ls-outdated)  shift; __list__outdated_packages "$@" ;;

    is-available) shift; is_package_available "$@" ;;

    is-installed)
        shift
        PACKAGE_SPEC=
        PACKAGE_SPEC="$(inspect_package_spec "$1")"
        is_package_installed "$PACKAGE_SPEC"
        ;;

    is-outdated)
        shift
        PACKAGE_SPEC=
        PACKAGE_SPEC="$(inspect_package_spec "$1")"
        is_package__outdated "$PACKAGE_SPEC"
        ;;

    search)  shift; __search_packages "$@" ;;

    depends) shift; __show_packages_depended_by_the_given_package "$@" ;;
    fetch)   shift;        __fetch_resources_of_the_given_package "$@" ;;

    install) shift;   __install_the_given_packages "$@" ;;
  reinstall) shift; __reinstall_the_given_packages "$@" ;;
  uninstall) shift; __uninstall_the_given_packages "$@" ;;

    upgrade) shift; __upgrade_packages "$@" ;;

    upgrade-self)
             shift; __upgrade_self "$PPKG_UPGRAGE_URL" "$@" ;;

    logs)   shift;   __logs_the_given_installed_package "$@" ;;
    tree)   shift;   __tree_the_given_installed_package "$@" ;;
    bundle) shift; __bundle_the_given_installed_package "$@" ;;
    export) shift; __export_the_given_installed_package "$@" ;;

    integrate)
        shift
        case $1 in
            zsh)
                shift
                __integrate_zsh_completions "$PPKG_ZSH_COMPLETION_SCRIPT_URL" "$@"
                ;;
            *)  abort 1 "ppkg integrate $1: not support."
        esac
        ;;

    cleanup) shift; __cleanup ;;

    run)
        shift

        [ -z "$1" ] && abort 1 'no command is supplied to run.'

        [ "$1" = uppm ] && {
            shift
            "$UPPM" "$@"
            exit
        }

        unset DIRS1
        unset DIRS2
        unset DIRS3

        unset ROOT1
        unset ROOT2
        unset ROOT3

        ROOT1="$UPPM_HOME/installed"
        ROOT2="$NATIVE_PACKAGE_INSTALLED_ROOT"
        ROOT3="$PPKG_PACKAGE_INSTALLED_ROOT/$NATIVE_PLATFORM_NAME-$NATIVE_PLATFORM_VERS-$NATIVE_PLATFORM_ARCH"

        [ -n "$ROOT1" ] && DIRS1="$(find "$ROOT1" -maxdepth 1 -mindepth 1 -type d)"
        [ -n "$ROOT2" ] && DIRS2="$(find "$ROOT2" -maxdepth 1 -mindepth 1 -type l)"
        [ -n "$ROOT3" ] && DIRS3="$(find "$ROOT3" -maxdepth 1 -mindepth 1 -type l)"

        for DIR in $DIRS1 $DIRS2 $DIRS3
        do
            if [ -d  "$DIR/bin" ] ; then
                PATH="$DIR/bin:$PATH"
            fi

            if [ -d  "$DIR/sbin" ] ; then
                PATH="$DIR/sbin:$PATH"
            fi

            if [ -d  "$DIR/include" ] ; then
                CPPFLAGS="-I$DIR/include $CPPFLAGS"
            fi

            if [ -d  "$DIR/lib" ] ; then
                LDFLAGS="-L$DIR/lib -Wl,-rpath,$DIR/lib $LDFLAGS"
            fi

            if [ -d  "$DIR/lib/pkgconfig" ] ; then
                PKG_CONFIG_PATH="$DIR/lib/pkgconfig:$PKG_CONFIG_PATH"
            fi

            SHARED="$DIR/share"

            if [ -d "$SHARED" ] ; then
                if [ -d "$SHARED/pkgconfig" ] ; then
                    PKG_CONFIG_PATH="$SHARED/pkgconfig:$PKG_CONFIG_PATH"
                fi

                if [ -d  "$SHARED/aclocal" ] ; then
                    ACLOCAL_PATH="$SHARED/aclocal:$ACLOCAL_PATH"
                fi

                # https://gi.readthedocs.io/en/latest/tools/g-ir-scanner.html#environment-variables
                # https://help.gnome.org/admin//system-admin-guide/2.32/mimetypes-database.html.en

                for item in gir-1.0 mime
                do
                    if [ -d "$SHARED/$item" ] ; then
                        if [ -z "$XDG_DATA_DIRS" ] ; then
                            XDG_DATA_DIRS="$SHARED"
                        else
                            XDG_DATA_DIRS="$SHARED:$XDG_DATA_DIRS"
                        fi

                        break
                    fi
                done
            fi
        done

        export CPPFLAGS
        export CFLAGS
        export LDFLAG
        export PKG_CONFIG_PATH
        export ACLOCAL_PATH
        export XDG_DATA_DIRS

        #export -p

        "$@"
        ;;

    *)  abort 1 "unrecognized argument: $1"
esac

# }}}
